diff --git a/404.html b/404.html index e0ef11b3..556f249f 100644 --- a/404.html +++ b/404.html @@ -3,14 +3,14 @@ -Page Not Found | Honeycomb - - +Page Not Found | Honeycomb + +
-
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.

- - +
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/assets/css/styles.9b736390.css b/assets/css/styles.a562a02a.css similarity index 66% rename from assets/css/styles.9b736390.css rename to assets/css/styles.a562a02a.css index 93c1d2bc..1c11b65f 100644 --- a/assets/css/styles.9b736390.css +++ b/assets/css/styles.a562a02a.css @@ -1 +1 @@ -.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)}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}: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-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;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#3578e5;--ifm-color-primary-dark:#1d68e1;--ifm-color-primary-darker:#1b62d4;--ifm-color-primary-darkest:#1751af;--ifm-color-primary-light:#4e89e8;--ifm-color-primary-lighter:#5a91ea;--ifm-color-primary-lightest:#80aaef;--ifm-code-font-size:95%;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--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}.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)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{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)}.container_lyt7,.container_lyt7>svg,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,.tabList__CuJ{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{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)}.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,.collapsibleContent_i85q>:last-child,.footer__items,.tabItem_Ymn6>:last-child{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{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}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;top:0;left:0;visibility:hidden}.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{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter);content:""}.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__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);position:fixed;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;position:fixed;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{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,.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}#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}.docusaurus-highlight-code-line{background-color:#484d5b}.code-block-delete-line,.docusaurus-highlight-code-line{display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.code-block-delete-line{background-color:#ff000020;border-left:3px solid #ff000080}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.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}.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}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.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}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.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:"#"}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.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}: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)}.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}.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)}.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}.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}.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)}#__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}.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,html:not([data-theme]) .themedComponent--light_NU7w{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}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.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%}.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}.heroBanner_UJJx{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.buttons_pzbO{justify-content:center}.buttons_pzbO,.features_keug{align-items:center;display:flex}.features_keug{padding:2rem 0;width:100%}.featureImage_yA8i{height:200px;width:200px}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}: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}}@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,.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}.docItemContainer_F8PC{padding:0 .3rem}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}}@media screen and (max-width:966px){.heroBanner_UJJx{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}}@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 +.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)}.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}: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-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;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#3578e5;--ifm-color-primary-dark:#1d68e1;--ifm-color-primary-darker:#1b62d4;--ifm-color-primary-darkest:#1751af;--ifm-color-primary-light:#4e89e8;--ifm-color-primary-lighter:#5a91ea;--ifm-color-primary-lightest:#80aaef;--ifm-code-font-size:95%;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--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}.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)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{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)}.container_lyt7,.container_lyt7>svg,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,.tabList__CuJ{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{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)}.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,.collapsibleContent_i85q>:last-child,.footer__items,.tabItem_Ymn6>:last-child{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{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}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;top:0;left:0;visibility:hidden}.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{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter);content:""}.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__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{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);position:fixed;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;position:fixed;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{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,.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}#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}.docusaurus-highlight-code-line{background-color:#484d5b}.code-block-delete-line,.docusaurus-highlight-code-line{display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.code-block-delete-line{background-color:#ff000020;border-left:3px solid #ff000080}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.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}.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}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.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}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.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:"#"}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.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}: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)}.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}.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)}.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}.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}.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)}#__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}.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,html:not([data-theme]) .themedComponent--light_NU7w{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}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.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%}.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}.heroBanner_UJJx{overflow:hidden;padding:4rem 0;position:relative;text-align:center}.buttons_pzbO{justify-content:center}.buttons_pzbO,.features_keug{align-items:center;display:flex}.features_keug{padding:2rem 0;width:100%}.featureImage_yA8i{height:200px;width:200px}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}: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);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}}@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,.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}.docItemContainer_F8PC{padding:0 .3rem}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}}@media screen and (max-width:966px){.heroBanner_UJJx{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}}@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/assets/js/021ef33c.80aff6c5.js b/assets/js/021ef33c.80aff6c5.js deleted file mode 100644 index 726e591c..00000000 --- a/assets/js/021ef33c.80aff6c5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkhoneycomb_docs=self.webpackChunkhoneycomb_docs||[]).push([[7620],{5680:(e,t,o)=>{o.d(t,{xA:()=>p,yg:()=>y});var n=o(6540);function a(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 r(e){for(var t=1;t=0||(a[o]=e[o]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(a[o]=e[o])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},p=function(e){var t=c(e.components);return n.createElement(l.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 o=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(o),m=a,y=d["".concat(l,".").concat(m)]||d[m]||u[m]||i;return o?n.createElement(y,r(r({ref:t},p),{},{components:o})):n.createElement(y,r({ref:t},p))}));function y(e,t){var o=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=o.length,r=new Array(i);r[0]=m;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 c=2;c{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=o(8168),a=(o(6540),o(5680));const i={id:"ci_cd",slug:"/ci_cd",title:"Continuous Integration / Deployment",description:"Descriptions of the GitHub Actions for Honeycomb's CI/CD workflows"},r=void 0,s={unversionedId:"project_organization/ci_cd",id:"project_organization/ci_cd",title:"Continuous Integration / Deployment",description:"Descriptions of the GitHub Actions for Honeycomb's CI/CD workflows",source:"@site/docs/project_organization/ci_cd.mdx",sourceDirName:"project_organization",slug:"/ci_cd",permalink:"/honeycomb-docs/docs/ci_cd",draft:!1,editUrl:"https://github.com/brown-ccv/honeycomb-docs/edit/main/docs/project_organization/ci_cd.mdx",tags:[],version:"current",lastUpdatedAt:1714155016,formattedLastUpdatedAt:"Apr 26, 2024",frontMatter:{id:"ci_cd",slug:"/ci_cd",title:"Continuous Integration / Deployment",description:"Descriptions of the GitHub Actions for Honeycomb's CI/CD workflows"},sidebar:"mySidebar",previous:{title:"Environment Variables",permalink:"/honeycomb-docs/docs/environment_variables"},next:{title:"Local Application",permalink:"/honeycomb-docs/docs/local_application"}},l={},c=[{value:"What are Github Actions",id:"what-are-github-actions",level:2},{value:"Honeycomb's CI/CD Workflows",id:"honeycombs-cicd-workflows",level:2},{value:"Firebase",id:"firebase",level:3}],p={toc:c},d="wrapper";function u(e){let{components:t,...o}=e;return(0,a.yg)(d,(0,n.A)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs."),(0,a.yg)("h2",{id:"what-are-github-actions"},"What are Github Actions"),(0,a.yg)("p",null,(0,a.yg)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in ",(0,a.yg)("a",{parentName:"p",href:"https://docs.github.com/en/actions/reference/events-that-trigger-workflows"},"GitHub's documentation")),(0,a.yg)("p",null,"GitHub Actions are written as YML files inside the ",(0,a.yg)("inlineCode",{parentName:"p"},".github/workflows/")," folder of your repository."),(0,a.yg)("h2",{id:"honeycombs-cicd-workflows"},"Honeycomb's CI/CD Workflows"),(0,a.yg)("p",null,"Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"Home"),": The app does not expect event code triggers and photodiode spots."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"Clinic"),": The app expects event code triggers and photodiode spots.")),(0,a.yg)("admonition",{type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.")),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"pull_request.yaml"),": Every time a Pull Request (PR) is created the software is built and tests are run for all platforms with ",(0,a.yg)("inlineCode",{parentName:"p"},"home")," and ",(0,a.yg)("inlineCode",{parentName:"p"},"clinic")," settings. This workflow does not upload desktop installers.")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"release.yml"),": Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"workflow-package.yaml"),": Create installers for any/all platforms for the ",(0,a.yg)("inlineCode",{parentName:"p"},"home")," and/or ",(0,a.yg)("inlineCode",{parentName:"p"},"clinic")," setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected."),(0,a.yg)("admonition",{parentName:"li",type:"note"},(0,a.yg)("p",{parentName:"admonition"},"On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their ",(0,a.yg)("a",{parentName:"p",href:"https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions"},"official documentation"),"."))),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"workflow-delete-artifacts.yaml"),": On-demand workflow for deleting artifacts form your GitHub repository. This can be useful when the ",(0,a.yg)("inlineCode",{parentName:"p"},"package.yaml")," workflow is run multiple times and you want to delete the artifacts from previous runs."))),(0,a.yg)("h3",{id:"firebase"},"Firebase"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"firebase-hosting-merge.yaml"),": Deploys the web version of the application to Firebase when a PR is merged into the ",(0,a.yg)("inlineCode",{parentName:"li"},"main")," branch."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"firebase-hosting-pull-request.yaml"),": Creates a preview version of the application with Firebase when a PR is opened.",(0,a.yg)("admonition",{parentName:"li",type:"warning"},(0,a.yg)("p",{parentName:"admonition"},"While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.")))),(0,a.yg)("admonition",{type:"note"},(0,a.yg)("p",{parentName:"admonition"},"These workflows may be safely deleted if you are not planning to ever use Firebase.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/021ef33c.9e8bdec4.js b/assets/js/021ef33c.9e8bdec4.js new file mode 100644 index 00000000..5b061871 --- /dev/null +++ b/assets/js/021ef33c.9e8bdec4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkhoneycomb_docs=self.webpackChunkhoneycomb_docs||[]).push([[7620],{5680:(e,t,o)=>{o.d(t,{xA:()=>p,yg:()=>y});var n=o(6540);function a(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 r(e){for(var t=1;t=0||(a[o]=e[o]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(a[o]=e[o])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):r(r({},t),e)),o},p=function(e){var t=c(e.components);return n.createElement(l.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 o=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(o),m=a,y=d["".concat(l,".").concat(m)]||d[m]||u[m]||i;return o?n.createElement(y,r(r({ref:t},p),{},{components:o})):n.createElement(y,r({ref:t},p))}));function y(e,t){var o=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=o.length,r=new Array(i);r[0]=m;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 c=2;c{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var n=o(8168),a=(o(6540),o(5680));const i={id:"ci_cd",slug:"/ci_cd",title:"Continuous Integration / Deployment",description:"Descriptions of the GitHub Actions for Honeycomb's CI/CD workflows"},r=void 0,s={unversionedId:"project_organization/ci_cd",id:"project_organization/ci_cd",title:"Continuous Integration / Deployment",description:"Descriptions of the GitHub Actions for Honeycomb's CI/CD workflows",source:"@site/docs/project_organization/ci_cd.mdx",sourceDirName:"project_organization",slug:"/ci_cd",permalink:"/honeycomb-docs/docs/ci_cd",draft:!1,editUrl:"https://github.com/brown-ccv/honeycomb-docs/edit/main/docs/project_organization/ci_cd.mdx",tags:[],version:"current",lastUpdatedAt:1715090738,formattedLastUpdatedAt:"May 7, 2024",frontMatter:{id:"ci_cd",slug:"/ci_cd",title:"Continuous Integration / Deployment",description:"Descriptions of the GitHub Actions for Honeycomb's CI/CD workflows"},sidebar:"mySidebar",previous:{title:"Environment Variables",permalink:"/honeycomb-docs/docs/environment_variables"},next:{title:"Local Application",permalink:"/honeycomb-docs/docs/local_application"}},l={},c=[{value:"What are Github Actions",id:"what-are-github-actions",level:2},{value:"Honeycomb's CI/CD Workflows",id:"honeycombs-cicd-workflows",level:2},{value:"Firebase",id:"firebase",level:3}],p={toc:c},d="wrapper";function u(e){let{components:t,...o}=e;return(0,a.yg)(d,(0,n.A)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs."),(0,a.yg)("h2",{id:"what-are-github-actions"},"What are Github Actions"),(0,a.yg)("p",null,(0,a.yg)("a",{parentName:"p",href:"https://docs.github.com/en/actions"},"GitHub Actions")," automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in ",(0,a.yg)("a",{parentName:"p",href:"https://docs.github.com/en/actions/reference/events-that-trigger-workflows"},"GitHub's documentation")),(0,a.yg)("p",null,"GitHub Actions are written as YML files inside the ",(0,a.yg)("inlineCode",{parentName:"p"},".github/workflows/")," folder of your repository."),(0,a.yg)("h2",{id:"honeycombs-cicd-workflows"},"Honeycomb's CI/CD Workflows"),(0,a.yg)("p",null,"Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"Home"),": The app does not expect event code triggers and photodiode spots."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"Clinic"),": The app expects event code triggers and photodiode spots.")),(0,a.yg)("admonition",{type:"tip"},(0,a.yg)("p",{parentName:"admonition"},"Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.")),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"pull_request.yaml"),": Every time a Pull Request (PR) is created the software is built and tests are run for all platforms with ",(0,a.yg)("inlineCode",{parentName:"p"},"home")," and ",(0,a.yg)("inlineCode",{parentName:"p"},"clinic")," settings. This workflow does not upload desktop installers.")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"release.yml"),": Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.")),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"workflow-package.yaml"),": Create installers for any/all platforms for the ",(0,a.yg)("inlineCode",{parentName:"p"},"home")," and/or ",(0,a.yg)("inlineCode",{parentName:"p"},"clinic")," setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected."),(0,a.yg)("admonition",{parentName:"li",type:"note"},(0,a.yg)("p",{parentName:"admonition"},"On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their ",(0,a.yg)("a",{parentName:"p",href:"https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions"},"official documentation"),"."))),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("p",{parentName:"li"},(0,a.yg)("inlineCode",{parentName:"p"},"workflow-delete-artifacts.yaml"),": On-demand workflow for deleting artifacts form your GitHub repository. This can be useful when the ",(0,a.yg)("inlineCode",{parentName:"p"},"package.yaml")," workflow is run multiple times and you want to delete the artifacts from previous runs."))),(0,a.yg)("h3",{id:"firebase"},"Firebase"),(0,a.yg)("ul",null,(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"firebase-hosting-merge.yaml"),": Deploys the web version of the application to Firebase when a PR is merged into the ",(0,a.yg)("inlineCode",{parentName:"li"},"main")," branch."),(0,a.yg)("li",{parentName:"ul"},(0,a.yg)("inlineCode",{parentName:"li"},"firebase-hosting-pull-request.yaml"),": Creates a preview version of the application with Firebase when a PR is opened.",(0,a.yg)("admonition",{parentName:"li",type:"warning"},(0,a.yg)("p",{parentName:"admonition"},"While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.")))),(0,a.yg)("admonition",{type:"note"},(0,a.yg)("p",{parentName:"admonition"},"These workflows may be safely deleted if you are not planning to ever use Firebase.")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/038eb3f9.50b153c3.js b/assets/js/038eb3f9.17395074.js similarity index 57% rename from assets/js/038eb3f9.50b153c3.js rename to assets/js/038eb3f9.17395074.js index b368d005..f426b5dc 100644 --- a/assets/js/038eb3f9.50b153c3.js +++ b/assets/js/038eb3f9.17395074.js @@ -1 +1 @@ -"use strict";(self.webpackChunkhoneycomb_docs=self.webpackChunkhoneycomb_docs||[]).push([[6259],{5680:(e,t,o)=>{o.d(t,{xA:()=>p,yg:()=>m});var r=o(6540);function n(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 r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function s(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var l=r.createContext({}),c=function(e){var t=r.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):s(s({},t),e)),o},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(o),f=n,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||a;return o?r.createElement(m,s(s({ref:t},p),{},{components:o})):r.createElement(m,s({ref:t},p))}));function m(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=o.length,s=new Array(a);s[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:n,s[1]=i;for(var c=2;c{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=o(8168),n=(o(6540),o(5680));const a={id:"software_prerecs",title:"Software Prerequisites"},s=void 0,i={unversionedId:"software_prerecs",id:"version-1.1.0/software_prerecs",title:"Software Prerequisites",description:"Windows",source:"@site/versioned_docs/version-1.1.0/software_prerecs.md",sourceDirName:".",slug:"/software_prerecs",permalink:"/honeycomb-docs/docs/1.1.0/software_prerecs",draft:!1,editUrl:"https://github.com/brown-ccv/honeycomb-docs/edit/main/versioned_docs/version-1.1.0/software_prerecs.md",tags:[],version:"1.1.0",lastUpdatedAt:1714155016,formattedLastUpdatedAt:"Apr 26, 2024",frontMatter:{id:"software_prerecs",title:"Software Prerequisites"}},l={},c=[{value:"Windows",id:"windows",level:2},{value:"Visual Studio",id:"visual-studio",level:4},{value:"Python",id:"python",level:4},{value:"Node.js",id:"nodejs",level:4},{value:"Git bash",id:"git-bash",level:4},{value:"Note: restart computer after all installs are complete",id:"note-restart-computer-after-all-installs-are-complete",level:4}],p={toc:c},d="wrapper";function u(e){let{components:t,...o}=e;return(0,n.yg)(d,(0,r.A)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("h2",{id:"windows"},"Windows"),(0,n.yg)("h4",{id:"visual-studio"},"Visual Studio"),(0,n.yg)("p",null,"Install the latest version of Visual Studio (",(0,n.yg)("a",{parentName:"p",href:"https://visualstudio.microsoft.com/downloads/"},"https://visualstudio.microsoft.com/downloads/"),") with the Desktop Development for C++ Workflow.\nTo add the workflow, follow the instructions linked below:\n",(0,n.yg)("a",{parentName:"p",href:"https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify"},"https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify"),"."),(0,n.yg)("h4",{id:"python"},"Python"),(0,n.yg)("p",null,"Install Python. For new Python users, we recommend installing via Anaconda: ",(0,n.yg)("a",{parentName:"p",href:"https://docs.anaconda.com/anaconda/install/windows/"},"https://docs.anaconda.com/anaconda/install/windows/")),(0,n.yg)("h4",{id:"nodejs"},"Node.js"),(0,n.yg)("p",null,"Install Node.js: ",(0,n.yg)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"https://nodejs.org/en/download/")),(0,n.yg)("h4",{id:"git-bash"},"Git bash"),(0,n.yg)("p",null,"Install git bash: ",(0,n.yg)("a",{parentName:"p",href:"https://git-scm.com/downloads"},"https://git-scm.com/downloads")),(0,n.yg)("h4",{id:"note-restart-computer-after-all-installs-are-complete"},"Note: restart computer after all installs are complete"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkhoneycomb_docs=self.webpackChunkhoneycomb_docs||[]).push([[6259],{5680:(e,t,o)=>{o.d(t,{xA:()=>p,yg:()=>m});var r=o(6540);function n(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 r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function s(e){for(var t=1;t=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}var l=r.createContext({}),c=function(e){var t=r.useContext(l),o=t;return e&&(o="function"==typeof e?e(t):s(s({},t),e)),o},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var o=e.components,n=e.mdxType,a=e.originalType,l=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),d=c(o),f=n,m=d["".concat(l,".").concat(f)]||d[f]||u[f]||a;return o?r.createElement(m,s(s({ref:t},p),{},{components:o})):r.createElement(m,s({ref:t},p))}));function m(e,t){var o=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=o.length,s=new Array(a);s[0]=f;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[d]="string"==typeof e?e:n,s[1]=i;for(var c=2;c{o.r(t),o.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=o(8168),n=(o(6540),o(5680));const a={id:"software_prerecs",title:"Software Prerequisites"},s=void 0,i={unversionedId:"software_prerecs",id:"version-1.1.0/software_prerecs",title:"Software Prerequisites",description:"Windows",source:"@site/versioned_docs/version-1.1.0/software_prerecs.md",sourceDirName:".",slug:"/software_prerecs",permalink:"/honeycomb-docs/docs/1.1.0/software_prerecs",draft:!1,editUrl:"https://github.com/brown-ccv/honeycomb-docs/edit/main/versioned_docs/version-1.1.0/software_prerecs.md",tags:[],version:"1.1.0",lastUpdatedAt:1715090738,formattedLastUpdatedAt:"May 7, 2024",frontMatter:{id:"software_prerecs",title:"Software Prerequisites"}},l={},c=[{value:"Windows",id:"windows",level:2},{value:"Visual Studio",id:"visual-studio",level:4},{value:"Python",id:"python",level:4},{value:"Node.js",id:"nodejs",level:4},{value:"Git bash",id:"git-bash",level:4},{value:"Note: restart computer after all installs are complete",id:"note-restart-computer-after-all-installs-are-complete",level:4}],p={toc:c},d="wrapper";function u(e){let{components:t,...o}=e;return(0,n.yg)(d,(0,r.A)({},p,o,{components:t,mdxType:"MDXLayout"}),(0,n.yg)("h2",{id:"windows"},"Windows"),(0,n.yg)("h4",{id:"visual-studio"},"Visual Studio"),(0,n.yg)("p",null,"Install the latest version of Visual Studio (",(0,n.yg)("a",{parentName:"p",href:"https://visualstudio.microsoft.com/downloads/"},"https://visualstudio.microsoft.com/downloads/"),") with the Desktop Development for C++ Workflow.\nTo add the workflow, follow the instructions linked below:\n",(0,n.yg)("a",{parentName:"p",href:"https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify"},"https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify"),"."),(0,n.yg)("h4",{id:"python"},"Python"),(0,n.yg)("p",null,"Install Python. For new Python users, we recommend installing via Anaconda: ",(0,n.yg)("a",{parentName:"p",href:"https://docs.anaconda.com/anaconda/install/windows/"},"https://docs.anaconda.com/anaconda/install/windows/")),(0,n.yg)("h4",{id:"nodejs"},"Node.js"),(0,n.yg)("p",null,"Install Node.js: ",(0,n.yg)("a",{parentName:"p",href:"https://nodejs.org/en/download/"},"https://nodejs.org/en/download/")),(0,n.yg)("h4",{id:"git-bash"},"Git bash"),(0,n.yg)("p",null,"Install git bash: ",(0,n.yg)("a",{parentName:"p",href:"https://git-scm.com/downloads"},"https://git-scm.com/downloads")),(0,n.yg)("h4",{id:"note-restart-computer-after-all-installs-are-complete"},"Note: restart computer after all installs are complete"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/03efd2cf.c18a52de.js b/assets/js/03efd2cf.c18a52de.js new file mode 100644 index 00000000..d8194a70 --- /dev/null +++ b/assets/js/03efd2cf.c18a52de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkhoneycomb_docs=self.webpackChunkhoneycomb_docs||[]).push([[5896],{5680:(e,t,a)=>{a.d(t,{xA:()=>c,yg:()=>y});var n=a(6540);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=0||(i[a]=e[a]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(i[a]=e[a])}return i}var l=n.createContext({}),p=function(e){var t=n.useContext(l),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(l.Provider,{value:t},e.children)},g="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,i=e.mdxType,r=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),g=p(a),u=i,y=g["".concat(l,".").concat(u)]||g[u]||d[u]||r;return a?n.createElement(y,o(o({ref:t},c),{},{components:a})):n.createElement(y,o({ref:t},c))}));function y(e,t){var a=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=a.length,o=new Array(r);o[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[g]="string"==typeof e?e:i,o[1]=s;for(var p=2;p{a.r(t),a.d(t,{assets:()=>u,contentTitle:()=>g,default:()=>b,frontMatter:()=>c,metadata:()=>d,toc:()=>y});var n=a(8168),i=(a(6540),a(5680));const r=a.p+"assets/images/firebase-actions-e13d5d73602640c80b12e924ea7843b6.png",o=a.p+"assets/images/firebase-console-settings-0a6f9d645eb45de659a7b4b784467625.png",s=a.p+"assets/images/firebase-web-credentials-2fe52b2547f94448997f6d311c76412f.png",l=a.p+"assets/images/firestore-create-study-1e75d836c67200b199878dcf4772fe50.png",p=a.p+"assets/images/firestore-example-study-8c600c7203ca68515ab663645af36874.png",c={id:"firebase",slug:"/firebase",title:"Firebase",description:"Guide for connecting Honeycomb to a Firebase project"},g=void 0,d={unversionedId:"deployments/firebase",id:"version-3.3.x/deployments/firebase",title:"Firebase",description:"Guide for connecting Honeycomb to a Firebase project",source:"@site/versioned_docs/version-3.3.x/deployments/firebase.mdx",sourceDirName:"deployments",slug:"/firebase",permalink:"/honeycomb-docs/docs/3.3.x/firebase",draft:!1,editUrl:"https://github.com/brown-ccv/honeycomb-docs/edit/main/versioned_docs/version-3.3.x/deployments/firebase.mdx",tags:[],version:"3.3.x",lastUpdatedAt:1715090738,formattedLastUpdatedAt:"May 7, 2024",frontMatter:{id:"firebase",slug:"/firebase",title:"Firebase",description:"Guide for connecting Honeycomb to a Firebase project"},sidebar:"mySidebar",previous:{title:"Local Application",permalink:"/honeycomb-docs/docs/3.3.x/local_application"},next:{title:"PsiTurk",permalink:"/honeycomb-docs/docs/3.3.x/psiturk"}},u={},y=[{value:"Setting up Firebase",id:"setting-up-firebase",level:2},{value:"Adding Products",id:"adding-products",level:3},{value:"Installing the Command Line Interface",id:"installing-the-command-line-interface",level:3},{value:"Connecting Your Firebase Project",id:"connecting-your-firebase-project",level:3},{value:"Developing With Firebase",id:"developing-with-firebase",level:2},{value:"Deploying on Firebase",id:"deploying-on-firebase",level:2},{value:"Managing Data",id:"managing-data",level:2},{value:"Setting up a Service Account",id:"setting-up-a-service-account",level:3},{value:"Using the CLI Script",id:"using-the-cli-script",level:3},{value:"Further Reading",id:"further-reading",level:2},{value:"Security Rules",id:"security-rules",level:3},{value:"Registering Studies",id:"registering-studies",level:4}],m={toc:y},h="wrapper";function b(e){let{components:t,...a}=e;return(0,i.yg)(h,(0,n.A)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,i.yg)("p",null,"Honeycomb comes with methods and configurations to deploy tasks with ",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/"},"Firebase"),". These tools make it possible to reach a wider audience by hosting your task online."),(0,i.yg)("h2",{id:"setting-up-firebase"},"Setting up Firebase"),(0,i.yg)("admonition",{type:"info"},(0,i.yg)("p",{parentName:"admonition"},"Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud."),(0,i.yg)("p",{parentName:"admonition"},"Otherwise, a ",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/"},"personal Firebase account")," can be created for free. Please follow the ",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/docs/projects/learn-more#setting_up_a_firebase_project_and_registering_apps"},"firebase documentation")," for creating a new project.")),(0,i.yg)("h3",{id:"adding-products"},"Adding Products"),(0,i.yg)("p",null,"First we'll configure ",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/docs/hosting"},"Firebase Hosting")," and ",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/docs/firestore"},"Cloud Firestore")," on your project."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Log in to Firebase with your Google account on the ",(0,i.yg)("a",{parentName:"p",href:"https://console.firebase.google.com/"},"Firebase console"))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Navigate to your project from the console")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Register a new web app to your project (",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/docs/web/setup#register-app"},"Register your app"),")"),(0,i.yg)("admonition",{parentName:"li",type:"note"},(0,i.yg)("p",{parentName:"admonition"},"We recommend giving your web app the same name as your task's repository"))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Add Firestore Database to your project (",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/docs/firestore/quickstart#create"},"Create a Cloud Firestore database"),")"),(0,i.yg)("admonition",{parentName:"li",type:"note"},(0,i.yg)("p",{parentName:"admonition"},"Choose ",(0,i.yg)("inlineCode",{parentName:"p"},"production mode"),' for the starting mode and the default "Cloud Firestore Location"')))),(0,i.yg)("p",null,"The Firebase project is now fully set up! Now we'll connect your task to that project from your computer."),(0,i.yg)("h3",{id:"installing-the-command-line-interface"},"Installing the Command Line Interface"),(0,i.yg)("p",null,"The Firebase CLI is installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="Login to Firebase"',title:'"Login',to:!0,'Firebase"':!0},"firebase login\n")),(0,i.yg)("p",null,(0,i.yg)("em",{parentName:"p"},"A ",(0,i.yg)("inlineCode",{parentName:"em"},"command not found")," error usually indicates firebase-tools has not been installed correctly. Re-running ",(0,i.yg)("inlineCode",{parentName:"em"},"npm install -g firebase-tools")," should fix this issue.")),(0,i.yg)("h3",{id:"connecting-your-firebase-project"},"Connecting Your Firebase Project"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},"Change the default project name of your task in ",(0,i.yg)("inlineCode",{parentName:"li"},".firebaserc"))),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-json",metastring:'title=".firebaserc" showLineNumbers',title:'".firebaserc"',showLineNumbers:!0},'{\n "projects": {\n "default": ""\n }\n}\n')),(0,i.yg)("ol",{start:2},(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Copy the web app credentials from the Firebase console to the corresponding variables in ",(0,i.yg)("inlineCode",{parentName:"p"},".env.firebase")),(0,i.yg)("ol",{parentName:"li"},(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Return to your project on the ",(0,i.yg)("a",{parentName:"p",href:"https://console.firebase.google.com/"},"Firebase console"))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Navigate to your project setting"),(0,i.yg)("img",{src:o,alt:"Firebase project settings"})),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the ",(0,i.yg)("inlineCode",{parentName:"p"},".env.firebase")," file in the ",(0,i.yg)("inlineCode",{parentName:"p"},"env")," folder of your Honeycomb task repo"),(0,i.yg)("img",{src:s,alt:"Firebase web credentials"}),(0,i.yg)("br",null),(0,i.yg)("br",null),(0,i.yg)("pre",{parentName:"li"},(0,i.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="env/.env.firebase"',title:'"env/.env.firebase"'},'REACT_APP_FIREBASE="true"\nREACT_APP_apiKey=\nREACT_APP_authDomain=\nREACT_APP_projectId=\nREACT_APP_storageBucket=\nREACT_APP_messagingSenderId=\nREACT_APP_appId=\n')),(0,i.yg)("p",{parentName:"li"},(0,i.yg)("em",{parentName:"p"},"Additional variables may be present in the console, they do not need to be copied."))))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Deploy the default ",(0,i.yg)("a",{parentName:"p",href:"https://firebase.google.com/docs/firestore/security/get-started"},"Firestore security rules")))),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="Deploy Firestore rules"',title:'"Deploy',Firestore:!0,'rules"':!0},"firebase deploy --only firestore:rules\n")),(0,i.yg)("p",null,"Your task is now connected to an initialized Firebase project!"),(0,i.yg)("h2",{id:"developing-with-firebase"},"Developing With Firebase"),(0,i.yg)("p",null,(0,i.yg)("em",{parentName:"p"},"Two terminal windows must be used while developing for Firebase. See ",(0,i.yg)("a",{parentName:"em",href:"https://code.visualstudio.com/docs/terminal/basics#_groups-split-panes"},"here")," for instructions on splitting terminals in VSCode.")),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="Run Honeycomb with Firebase Enabled"',title:'"Run',Honeycomb:!0,with:!0,Firebase:!0,'Enabled"':!0},"npm run dev:firebase\n")),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="Start the Firebase Emulators"',title:'"Start',the:!0,Firebase:!0,'Emulators"':!0},"npm run firebase:emulators:start\n")),(0,i.yg)("p",null,"Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. It may be viewed on ",(0,i.yg)("a",{parentName:"p",href:"http://localhost:4000/firestore"},"localhost:4000"),"."),(0,i.yg)("admonition",{type:"info"},(0,i.yg)("p",{parentName:"admonition"},"Honeycomb populates the Firestore emulators with the study ",(0,i.yg)("inlineCode",{parentName:"p"},"s1")," and participant ",(0,i.yg)("inlineCode",{parentName:"p"},"p1"),".")),(0,i.yg)("h2",{id:"deploying-on-firebase"},"Deploying on Firebase"),(0,i.yg)("p",null,"Firebase deployments are handled automatically following ",(0,i.yg)("a",{parentName:"p",href:"ci_cd"},"Continuous Integration Continuous Development (CI/CD)")," practices using GitHub Actions. Here we will create custom actions that are connected to the task's Firebase project."),(0,i.yg)("p",null,"Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear."),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="Initialize Firebase hosting via Github actions"',title:'"Initialize',Firebase:!0,hosting:!0,via:!0,Github:!0,'actions"':!0},"firebase init hosting:github\n")),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},"The window should log you in automatically; if not, follow the prompts to log in with the same account you used in the console"),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("inlineCode",{parentName:"li"},"/")," refers to the name of your repository in Github - be sure it's typed correctly!"),(0,i.yg)("li",{parentName:"ol"},"Enter ",(0,i.yg)("inlineCode",{parentName:"li"},"y"),' for the prompt "Set up the workflow to run a build script before every deploy?"'),(0,i.yg)("li",{parentName:"ol"},"Enter ",(0,i.yg)("inlineCode",{parentName:"li"},"npm install && npm run build:firebase"),' for the prompt "What script should be run before every deploy?"'),(0,i.yg)("li",{parentName:"ol"},"Enter ",(0,i.yg)("inlineCode",{parentName:"li"},"y")," to overwrite the current workflow file"),(0,i.yg)("li",{parentName:"ol"},"Enter ",(0,i.yg)("inlineCode",{parentName:"li"},"y"),' for the prompt "Set up automatic deployment to your site\'s live channel when a PR is merged?"'),(0,i.yg)("li",{parentName:"ol"},"Enter ",(0,i.yg)("inlineCode",{parentName:"li"},"main"),' for the prompt "What is the name of the GitHub branch associated with your site\'s live channel?"'),(0,i.yg)("li",{parentName:"ol"},"Enter ",(0,i.yg)("inlineCode",{parentName:"li"},"y")," to overwrite the current workflow file")),(0,i.yg)("p",null,"Firebase will update the files ",(0,i.yg)("inlineCode",{parentName:"p"},"firebase-hosting-pull-request.yml")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"firebase-hosting-merge.yml")," inside the ",(0,i.yg)("inlineCode",{parentName:"p"},".github/workflows/")," directory. Ensure the correct run script is present in both files."),(0,i.yg)("img",{src:r,alt:"Github actions created by firebase"}),(0,i.yg)("h2",{id:"managing-data"},"Managing Data"),(0,i.yg)("p",null,"Honeycomb ships with a CLI script for managing data in Firebase. A local service account must be created in order to use it."),(0,i.yg)("h3",{id:"setting-up-a-service-account"},"Setting up a Service Account"),(0,i.yg)("p",null,"Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically."),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Return to the project settings your project on the ",(0,i.yg)("a",{parentName:"p",href:"https://console.firebase.google.com/"},"Firebase console")),(0,i.yg)("img",{src:o,alt:"Firebase project settings"})),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},'Click on the "Service accounts" tab')),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},'Near the bottom, click "Generate new Private key" and "Generate Key"')),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Rename the key ",(0,i.yg)("inlineCode",{parentName:"p"},"firebase-service-account.json")," and move it to the root directory of your task - be sure the file looks grayed out and is not picked up by git!"))),(0,i.yg)("admonition",{type:"danger"},(0,i.yg)("p",{parentName:"admonition"},"A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and ",(0,i.yg)("strong",{parentName:"p"},"never committed to GitHub."))),(0,i.yg)("h3",{id:"using-the-cli-script"},"Using the CLI Script"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-bash",metastring:'title="Script Usage"',title:'"Script','Usage"':!0},"npm run cli\n")),(0,i.yg)("p",null,"The CLI script will guide you through the steps needed to manage your data appropriately:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Whether you wish to download or delete data")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Entering the ID of a given study")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Entering the ID of a given participant on that study")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Selecting the sessions to download/delete"),(0,i.yg)("admonition",{parentName:"li",type:"info"},(0,i.yg)("kbd",null,"SPACE")," selects a single session and ",(0,i.yg)("kbd",null,"A")," toggles every session"))),(0,i.yg)("admonition",{type:"note"},(0,i.yg)("p",{parentName:"admonition"},"The download script will prompt you for where the data should be saved. It defaults to ",(0,i.yg)("inlineCode",{parentName:"p"},"."),", which is your current folder. The folder must exist before running the script.")),(0,i.yg)("h2",{id:"further-reading"},"Further Reading"),(0,i.yg)("p",null,(0,i.yg)("em",{parentName:"p"},"The ",(0,i.yg)("a",{parentName:"em",href:"https://firebase.google.com/docs/emulator-suite"},"Firebase Documentation")," details its Emulator Suite in much greater detail.")),(0,i.yg)("h3",{id:"security-rules"},"Security Rules"),(0,i.yg)("p",null,"Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task."),(0,i.yg)("p",null,"Firestore rules are defined in the ",(0,i.yg)("inlineCode",{parentName:"p"},"firestore.rules")," file in the home directory. Note the highlighted lines:"),(0,i.yg)("pre",null,(0,i.yg)("code",{parentName:"pre",className:"language-firestore-security-rules",metastring:'title="firestore.rules" showLineNumbers',title:'"firestore.rules"',showLineNumbers:!0},"rules_version = '2';\nservice cloud.firestore {\n match /databases/{database}/documents {\n match /participant_responses/{studyID}/participants/{participantID} {\n allow create, read:\n // highlight-start\n if\n // Allows any combination of studyID and participantID to be created in Firebase\n true\n // participantID must be in the registered_participants array in the registered_studies/{studyID} document\n // participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;\n // highlight-end\n\n // experimentID must be in the data subcollection\n match /data/{experimentID} {\n allow create, read: if true\n\n // trialID must be in the trials subcollection\n match /trials/{trialID} {\n allow create, read: if true\n }\n }\n }\n }\n}\n")),(0,i.yg)("p",null,"Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at ",(0,i.yg)("inlineCode",{parentName:"p"},"/databases/{database}/documents/participant_responses/{studyID}/participants/{participantID}")," where ",(0,i.yg)("inlineCode",{parentName:"p"},"studyID")," is a given study and ",(0,i.yg)("inlineCode",{parentName:"p"},"participantID")," is a given participant within that study."),(0,i.yg)("p",null,"Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must use the ",(0,i.yg)("a",{parentName:"p",href:"#using-the-cli-script"},"CLI script")," to delete data."),(0,i.yg)("p",null,"Lines 6 through 10 defines our rule for creating a document for a given participant at ",(0,i.yg)("inlineCode",{parentName:"p"},"participant_responses/{studyID}/participants/{participantID}"),". Honeycomb ships with two possible rules:"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Line 8 specifies ",(0,i.yg)("inlineCode",{parentName:"p"},"true")," which allows any combination of ",(0,i.yg)("inlineCode",{parentName:"p"},"studyID")," and ",(0,i.yg)("inlineCode",{parentName:"p"},"participantID")," to be created in Firebase."),(0,i.yg)("admonition",{parentName:"li",type:"info"},(0,i.yg)("p",{parentName:"admonition"},"This is the default rule Honeycomb ships with. It is recommended to leave this rule as is and handle the registration of studies in another tool such as ",(0,i.yg)("a",{parentName:"p",href:"prolific"},"Prolific"),"."))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Line 10 only allows a ",(0,i.yg)("inlineCode",{parentName:"p"},"participantID")," to be created if the value is in an array called ",(0,i.yg)("inlineCode",{parentName:"p"},"registered_participants")," inside of a document at ",(0,i.yg)("inlineCode",{parentName:"p"},"registered_studies/{studyID}"),". This ensures pre-registration of every study and participant - the ",(0,i.yg)("a",{parentName:"p",href:"#registering-studies"},"next section")," explains how to register studies."))),(0,i.yg)("admonition",{type:"caution"},(0,i.yg)("p",{parentName:"admonition"},"Firestore rules define every valid path for data in your project. Attempting to connect anywhere besides the paths in your Firestore rules will be automatically denied, even if you have manually saved data elsewhere. This is why ",(0,i.yg)("inlineCode",{parentName:"p"},"firestore.rules")," contains the nested rules in lines 12 - 20. These should be left alone.")),(0,i.yg)("h4",{id:"registering-studies"},"Registering Studies"),(0,i.yg)("ol",null,(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Navigate to your Firestore Database in the ",(0,i.yg)("a",{parentName:"p",href:"https://console.firebase.google.com/"},"Firebase console"))),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},'Click "Start collection"')),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Enter ",(0,i.yg)("inlineCode",{parentName:"p"},"registered_studies")," as the collection ID")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Enter the id of your study as the document id")),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},'Click "Add Field".')),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},"Enter ",(0,i.yg)("inlineCode",{parentName:"p"},"registered_participants"),' as the field name, and set the type "array"')),(0,i.yg)("li",{parentName:"ol"},(0,i.yg)("p",{parentName:"li"},'Add the id of each study participant to the array as type "string"'),(0,i.yg)("div",{style:{textAlign:"center"}},(0,i.yg)("img",{src:l,alt:"Create a study",style:{maxHeight:"600px"}})))),(0,i.yg)("p",null,"The study should look like this when you're finished:"),(0,i.yg)("img",{src:p,alt:"Example study"}),(0,i.yg)("p",null,(0,i.yg)("strong",{parentName:"p"},"Additional studies are created as documents inside the ",(0,i.yg)("inlineCode",{parentName:"strong"},"registered_studies")," collection")))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/07af3df4.8c59d96b.js b/assets/js/07af3df4.8c59d96b.js new file mode 100644 index 00000000..35ecfdf5 --- /dev/null +++ b/assets/js/07af3df4.8c59d96b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkhoneycomb_docs=self.webpackChunkhoneycomb_docs||[]).push([[5214],{5680:(e,n,t)=>{t.d(n,{xA:()=>d,yg:()=>y});var i=t(6540);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 r(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 o(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var p=i.createContext({}),s=function(e){var n=i.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},d=function(e){var n=s(e.components);return i.createElement(p.Provider,{value:n},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},c=i.forwardRef((function(e,n){var t=e.components,a=e.mdxType,r=e.originalType,p=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=s(t),c=a,y=m["".concat(p,".").concat(c)]||m[c]||u[c]||r;return t?i.createElement(y,o(o({ref:n},d),{},{components:t})):i.createElement(y,o({ref:n},d))}));function y(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var r=t.length,o=new Array(r);o[0]=c;var l={};for(var p in n)hasOwnProperty.call(n,p)&&(l[p]=n[p]);l.originalType=e,l[m]="string"==typeof e?e:a,o[1]=l;for(var s=2;s{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>l,toc:()=>s});var i=t(8168),a=(t(6540),t(5680));const r={id:"npm_scripts",slug:"/npm_scripts",title:"NPM Scripts",description:"Guide to using the npm scripts needed for Honeycomb"},o=void 0,l={unversionedId:"project_organization/npm_scripts",id:"version-3.2.x/project_organization/npm_scripts",title:"NPM Scripts",description:"Guide to using the npm scripts needed for Honeycomb",source:"@site/versioned_docs/version-3.2.x/project_organization/npm_scripts.mdx",sourceDirName:"project_organization",slug:"/npm_scripts",permalink:"/honeycomb-docs/docs/3.2.x/npm_scripts",draft:!1,editUrl:"https://github.com/brown-ccv/honeycomb-docs/edit/main/versioned_docs/version-3.2.x/project_organization/npm_scripts.mdx",tags:[],version:"3.2.x",lastUpdatedAt:1715090738,formattedLastUpdatedAt:"May 7, 2024",frontMatter:{id:"npm_scripts",slug:"/npm_scripts",title:"NPM Scripts",description:"Guide to using the npm scripts needed for Honeycomb"},sidebar:"mySidebar",previous:{title:"Directory Structure",permalink:"/honeycomb-docs/docs/3.2.x/directory_structure"},next:{title:"Environment Variables",permalink:"/honeycomb-docs/docs/3.2.x/environment_variables"}},p={},s=[{value:"Start",id:"start",level:2},{value:"Firebase",id:"firebase",level:2},{value:"Dev",id:"dev",level:2},{value:"Firebase",id:"firebase-1",level:3},{value:"Build",id:"build",level:2},{value:"Package",id:"package",level:2},{value:"Miscellaneous",id:"miscellaneous",level:2}],d={toc:s},m="wrapper";function u(e){let{components:n,...t}=e;return(0,a.yg)(m,(0,i.A)({},d,t,{components:n,mdxType:"MDXLayout"}),(0,a.yg)("p",null,"Custom scripts for common shell commands can be written in ",(0,a.yg)("inlineCode",{parentName:"p"},"package.json")," and run the node package manager (NPM). All of the commands needed to develop, build, and deploy Honeycomb are written as scripts."),(0,a.yg)("p",null,"Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with."),(0,a.yg)("pre",null,(0,a.yg)("code",{parentName:"pre",className:"language-shell",metastring:'title="Executing an NPM Script"',title:'"Executing',an:!0,NPM:!0,'Script"':!0},"npm run
-
Version: 1.1.0

Automated Builds

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD:

Continuous Integration, Continuous Deployment: CI/CD or CICD refers to continuous integration and either continuous delivery or continuous deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation.

GitHub Actions are written as YAML files inside a .github/worflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows, Mac, and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds PsiTurk version when linux or all operating systems are selected
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage on private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need.

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file and allow to run.

The executable does not require installation of any additional software.

Uninstall the task

Windows

Go to System Settings: Add or remove programs. Look for the name of your task in the installed programs list, and Uninstall.

- - +
Version: 1.1.0

Automated Builds

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD:

Continuous Integration, Continuous Deployment: CI/CD or CICD refers to continuous integration and either continuous delivery or continuous deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation.

GitHub Actions are written as YAML files inside a .github/worflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows, Mac, and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds PsiTurk version when linux or all operating systems are selected
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage on private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need.

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file and allow to run.

The executable does not require installation of any additional software.

Uninstall the task

Windows

Go to System Settings: Add or remove programs. Look for the name of your task in the installed programs list, and Uninstall.

+ + \ No newline at end of file diff --git a/docs/1.1.0/configuration/index.html b/docs/1.1.0/configuration/index.html index 780078e8..17f9a8d3 100644 --- a/docs/1.1.0/configuration/index.html +++ b/docs/1.1.0/configuration/index.html @@ -3,14 +3,14 @@ -Configuration | Honeycomb - - +Configuration | Honeycomb + +
-
Version: 1.1.0

Configuration

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate whether they are mandatory, optional and needed during build (npm build) or run time (using the application executable or npm run dev)

  • ELECTRON_START_URL : URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode
  • EVENT_MARKER_PRODUCT_ID: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME : The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_AT_HOME: whether the app is being used in home mode (true) or clinic mode (false). During development and build time, you can run npm run dev:home/npm run dev:clinic or npm run build:home/npm run build:clinic to have the npm script set the variable for you. When running the production desktop application, you need to define it. Not defining this variable is equivalent to setting it to false. Build-time and run-time values need to be the same.
  • REACT_APP_PATIENT_ID : The default patient id to show when requesting a patient ID in userID. If not set, no default is shown (blank input box).
- - +
Version: 1.1.0

Configuration

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate whether they are mandatory, optional and needed during build (npm build) or run time (using the application executable or npm run dev)

  • ELECTRON_START_URL : URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode
  • EVENT_MARKER_PRODUCT_ID: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME : The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_AT_HOME: whether the app is being used in home mode (true) or clinic mode (false). During development and build time, you can run npm run dev:home/npm run dev:clinic or npm run build:home/npm run build:clinic to have the npm script set the variable for you. When running the production desktop application, you need to define it. Not defining this variable is equivalent to setting it to false. Build-time and run-time values need to be the same.
  • REACT_APP_PATIENT_ID : The default patient id to show when requesting a patient ID in userID. If not set, no default is shown (blank input box).
+ + \ No newline at end of file diff --git a/docs/1.1.0/event_triggers/index.html b/docs/1.1.0/event_triggers/index.html index c5b65208..ef2f1de3 100644 --- a/docs/1.1.0/event_triggers/index.html +++ b/docs/1.1.0/event_triggers/index.html @@ -3,16 +3,16 @@ -Set up event triggers | Honeycomb - - +Set up event triggers | Honeycomb + +
-
Version: 1.1.0

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set to the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here: https://github.com/neuromotion/USB-event-marker +

Version: 1.1.0

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set to the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here: https://github.com/neuromotion/USB-event-marker Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

Send event code triggers

Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from -./trigger and export as eventCodes

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncodewith the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

- - +./trigger and export as eventCodes

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncodewith the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

+ + \ No newline at end of file diff --git a/docs/1.1.0/folders/index.html b/docs/1.1.0/folders/index.html index 48d72d17..a2a1f1e9 100644 --- a/docs/1.1.0/folders/index.html +++ b/docs/1.1.0/folders/index.html @@ -3,14 +3,14 @@ -Project Organization | Honeycomb - - +Project Organization | Honeycomb + +
-
Version: 1.1.0

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used (and definitely not mutated), and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code. Below are descriptions of the main files and folders.

package.json

The package.json file contains metadata about your project and scripts to run tasks related to your task. The name should be updated to your task's name and scripts can be added as desired, but otherwise this file should not be edited manually. To remove or add a dependency use npm install or npm uninstall with the -D flag if installing a dev dependency.

The package-lock.json contains metadata about the package installation. It should never be manually updated.

assets/

The icons used for the installed applications are put here.

public/

The public directory contains files that are used as assets in the built app. The favicon.ico is the small icon you can see in the browser tab (on Chrome) - it is set to Brown's logo in the project. The index.html contains the shell of your website - the name displayed on the tab can be changed here, otherwise it shouldn't need to be edited. The scripts included in the file are for psiturk as are the files in the lib/ directory.

electron.js

This file contains all of the code relating to the electron app. This includes the event-marker, throwing errors via dialog windows, saving data, and reading files.

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes.

Note: the productId can be overwritten by the environment variable EVENT_MARKER_PRODUCT_ID

src/

This folder contains the code for the app, the vast majority of changes and code should go here.

App.js

This is the starting point for the app. The <Experiment> component initializes a jspsych experiment. This is also where communication is set up with the electron and psiturk processes.

App.css

This is where styling for the app is housed. If colors, fonts, spacing, etc. need to be set, do it here.

assets/

This folder contains any static files that are used by the app, such as images.

config/

In the config/ directory, there are .js files which contain settings for the different parts of the task. Every task should have a main config and a trigger config (assuming use of the event marker). The main config has all global settings for the task (such as whether it is in mturk mode or not), load the appropriate language file, and set up a default (or only) configuration object for the task. The trigger config has settings specific to the event marker and uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) as well as allows for mturk specific language. This also makes it easy to re-use common phrases in many places in the task.

lib/

The lib/ directory contains utility functions and markup that is used in the tasks. This allows for functions and html to be re-used wherever needed. The lib/utils.js file contains functions that are generally useful across many tasks, whereas lib/taskUtils.js contains functions specific to this task.

lib/markup

markup files should contain primarily templates for HTML that is used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

timelines

jspsych uses timelines to control what trials are displayed in what order. timelines can contain other timelines, which is why there may be several files in this directory. The main.js file should have the timeline that is called by App.js.

trials

jspsych uses trials as its base unit of an experiment. These trials do things such as display some stimulus or request a response.

- - +
Version: 1.1.0

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used (and definitely not mutated), and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code. Below are descriptions of the main files and folders.

package.json

The package.json file contains metadata about your project and scripts to run tasks related to your task. The name should be updated to your task's name and scripts can be added as desired, but otherwise this file should not be edited manually. To remove or add a dependency use npm install or npm uninstall with the -D flag if installing a dev dependency.

The package-lock.json contains metadata about the package installation. It should never be manually updated.

assets/

The icons used for the installed applications are put here.

public/

The public directory contains files that are used as assets in the built app. The favicon.ico is the small icon you can see in the browser tab (on Chrome) - it is set to Brown's logo in the project. The index.html contains the shell of your website - the name displayed on the tab can be changed here, otherwise it shouldn't need to be edited. The scripts included in the file are for psiturk as are the files in the lib/ directory.

electron.js

This file contains all of the code relating to the electron app. This includes the event-marker, throwing errors via dialog windows, saving data, and reading files.

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes.

Note: the productId can be overwritten by the environment variable EVENT_MARKER_PRODUCT_ID

src/

This folder contains the code for the app, the vast majority of changes and code should go here.

App.js

This is the starting point for the app. The <Experiment> component initializes a jspsych experiment. This is also where communication is set up with the electron and psiturk processes.

App.css

This is where styling for the app is housed. If colors, fonts, spacing, etc. need to be set, do it here.

assets/

This folder contains any static files that are used by the app, such as images.

config/

In the config/ directory, there are .js files which contain settings for the different parts of the task. Every task should have a main config and a trigger config (assuming use of the event marker). The main config has all global settings for the task (such as whether it is in mturk mode or not), load the appropriate language file, and set up a default (or only) configuration object for the task. The trigger config has settings specific to the event marker and uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) as well as allows for mturk specific language. This also makes it easy to re-use common phrases in many places in the task.

lib/

The lib/ directory contains utility functions and markup that is used in the tasks. This allows for functions and html to be re-used wherever needed. The lib/utils.js file contains functions that are generally useful across many tasks, whereas lib/taskUtils.js contains functions specific to this task.

lib/markup

markup files should contain primarily templates for HTML that is used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

timelines

jspsych uses timelines to control what trials are displayed in what order. timelines can contain other timelines, which is why there may be several files in this directory. The main.js file should have the timeline that is called by App.js.

trials

jspsych uses trials as its base unit of an experiment. These trials do things such as display some stimulus or request a response.

+ + \ No newline at end of file diff --git a/docs/1.1.0/index.html b/docs/1.1.0/index.html index a4b1332c..9a31e30b 100644 --- a/docs/1.1.0/index.html +++ b/docs/1.1.0/index.html @@ -3,14 +3,14 @@ -Introduction | Honeycomb - - +Introduction | Honeycomb + +
-
Version: 1.1.0

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy to install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

- - +
Version: 1.1.0

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy to install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

+ + \ No newline at end of file diff --git a/docs/1.1.0/npm_scripts/index.html b/docs/1.1.0/npm_scripts/index.html index 56fed3d1..4068623c 100644 --- a/docs/1.1.0/npm_scripts/index.html +++ b/docs/1.1.0/npm_scripts/index.html @@ -3,15 +3,15 @@ -NPM Scripts | Honeycomb - - +NPM Scripts | Honeycomb + +
-
Version: 1.1.0

NPM Scripts

In the project directory, you can run:

npm run dev

Runs npm start and npm run electron-dev concurrently. This may not play nicely with windows. If it doesn't, run npm start and npm run electron-dev from different terminal windows.

npm start

Runs the app in the development mode.

Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.

See the section about running tests for more information.

npm build

Creates a production build of the app (renderer). This must be done before running package:platform or the psiturk build instructions.

npm run package:platform

It correctly bundles creates electron packages for the given platform. It then creates an installer for that platform. The output can be found in /dist -platforms: windows, mac, linux.

Prerequisites

If not running this command on a windows machine, must have mono and wine installed.

npm run eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Run Electron

npm run electron

Run the built app.

npm run electron-dev

Run the current state of the code (un-built).

- - +
Version: 1.1.0

NPM Scripts

In the project directory, you can run:

npm run dev

Runs npm start and npm run electron-dev concurrently. This may not play nicely with windows. If it doesn't, run npm start and npm run electron-dev from different terminal windows.

npm start

Runs the app in the development mode.

Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.

See the section about running tests for more information.

npm build

Creates a production build of the app (renderer). This must be done before running package:platform or the psiturk build instructions.

npm run package:platform

It correctly bundles creates electron packages for the given platform. It then creates an installer for that platform. The output can be found in /dist +platforms: windows, mac, linux.

Prerequisites

If not running this command on a windows machine, must have mono and wine installed.

npm run eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Run Electron

npm run electron

Run the built app.

npm run electron-dev

Run the current state of the code (un-built).

+ + \ No newline at end of file diff --git a/docs/1.1.0/online_integration/index.html b/docs/1.1.0/online_integration/index.html index 2ec03c96..08cf91ec 100644 --- a/docs/1.1.0/online_integration/index.html +++ b/docs/1.1.0/online_integration/index.html @@ -3,18 +3,18 @@ -Deploy online | Honeycomb - - +Deploy online | Honeycomb + +
-
Version: 1.1.0

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a psiturk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. +

Version: 1.1.0

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a psiturk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

  • Build the application: npm run build

  • Move to the psiturkit directory: cd psiturkit

  • If it's the first time you're running the script:
    ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>

  • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):
    ./psiturk-it -u -p <PATH_TO_NEW_PSITURK_PROJECT>

Running psiturk

After that, just navigate to your newly created PsiTurk project directory.

shell> psiturk #start psiturk
psiturk> server on #start server
psiturk> debug #debug mode

Running on the Web

Running npm run build generates static content into the build directory that can be served using any static contents hosting service. The workflow .github/workflows/release-home-all.yml uploads the build directory to the gh-branch to serve the application on GitHub pages as an example. After a creating a tag, the workflow will run and your application will be served at <githubuser>.github.io/<repository>. -For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.
  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.
  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.
  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.
  5. To create the secret copy your private key e.g. xclip -sel clip < ~/.ssh/id_rsa and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.
  6. Make sure the publishing source for your repository is configured for gh-pages branch.
- - +For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.
  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.
  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.
  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.
  5. To create the secret copy your private key e.g. xclip -sel clip < ~/.ssh/id_rsa and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.
  6. Make sure the publishing source for your repository is configured for gh-pages branch.
+ + \ No newline at end of file diff --git a/docs/1.1.0/quick_start/index.html b/docs/1.1.0/quick_start/index.html index 2d74f27a..d4cbf1ad 100644 --- a/docs/1.1.0/quick_start/index.html +++ b/docs/1.1.0/quick_start/index.html @@ -3,18 +3,18 @@ -Quick Start | Honeycomb - - +Quick Start | Honeycomb + +
-
Version: 1.1.0

Quick Start

To start a new task locally, in development mode follow these steps:

1. Start your new task from our template repository

The simplest way to get started is creating a new repository using Honeycomb as a template.

Go to https://github.com/brown-ccv/honeycomb and click on Use this template on the top right. Then select the organization and the name of your repository and click on create repository from template

Alternatively, you can use GitHub CLI to create a new project based on the Honeycomb template repository. First, install GitHub CLI (https://cli.github.com/), then simply run on your terminal:

gh repo create your-new-task-name --template brown-ccv/honeycomb

You can now move into the directory that was just created

cd your-new-task-name

2. Change name and description

Update the package.json fields to reflect your app name and description, e.g. name, author, repository

3. Install the dependencies.

Electron Dependencies +

Version: 1.1.0

Quick Start

To start a new task locally, in development mode follow these steps:

1. Start your new task from our template repository

The simplest way to get started is creating a new repository using Honeycomb as a template.

Go to https://github.com/brown-ccv/honeycomb and click on Use this template on the top right. Then select the organization and the name of your repository and click on create repository from template

Alternatively, you can use GitHub CLI to create a new project based on the Honeycomb template repository. First, install GitHub CLI (https://cli.github.com/), then simply run on your terminal:

gh repo create your-new-task-name --template brown-ccv/honeycomb

You can now move into the directory that was just created

cd your-new-task-name

2. Change name and description

Update the package.json fields to reflect your app name and description, e.g. name, author, repository

3. Install the dependencies.

Electron Dependencies Honeycomb relies on Electron to package the cross-platform desktop applications. Before starting, you will need to install Electron's pre-requisites. You can find instructions here for your specific OS

Honeycomb npm packages Once Node.js is installed you will able to use npm commands in the terminal. To install the dependencies for HoneyComb run the following command at the terminal (remember you need cd your-new-task-name before)

npm install

4. Run the task in dev mode

To launch an electron window with the task with the inspector open to the console and will hot-reload when changes are made to the app

**For Mac and Linux:

npm run dev

**For Windows: You will need to open 2 terminals. In the first -and make sure you are in the task-<TASK NAME> repo directory- run the command:

npm start

In the second terminal - make sure you are in the task-<TASK NAME> repo directory-, run:

npm run electron-dev

5. Check out the data

The data is saved throughout the task to the users's app directory. This is logged at the beginning of the task wherever you ran npm run dev (for windows, instead in two different terminals ran npm start and npm run electron-dev). It is also stored in a folder that is generated by the app, which should be found on the desktop.

6. Quit The Task

If you want to quit in the middle of the task, you can use these keyboard shortcuts:

Ctrl+W (for PC/Windows)
Cmd+Q (for Mac)

Partial data will be saved.

7. Merge updates from honeycomb template repo

Honeycomb is an active project, and will be updated with new features over time. To merge the honeycomb template repository updates with your task, follow the following steps: -First time only:

git remote add honeycomb https://github.com/brown-ccv/honeycomb.git

Every time:

git fetch --all
git merge honeycomb/main --allow-unrelated histories

If there are any conflicts:

git stash

To merge:

git commit -a -m "merge honeycomb latest"
- - +First time only:

git remote add honeycomb https://github.com/brown-ccv/honeycomb.git

Every time:

git fetch --all
git merge honeycomb/main --allow-unrelated histories

If there are any conflicts:

git stash

To merge:

git commit -a -m "merge honeycomb latest"
+ + \ No newline at end of file diff --git a/docs/1.1.0/software_prerecs/index.html b/docs/1.1.0/software_prerecs/index.html index d9426069..ce76b553 100644 --- a/docs/1.1.0/software_prerecs/index.html +++ b/docs/1.1.0/software_prerecs/index.html @@ -3,16 +3,16 @@ -Software Prerequisites | Honeycomb - - +Software Prerequisites | Honeycomb + +
-
Version: 1.1.0

Software Prerequisites

Windows

Visual Studio

Install the latest version of Visual Studio (https://visualstudio.microsoft.com/downloads/) with the Desktop Development for C++ Workflow. +

Version: 1.1.0

Software Prerequisites

Windows

Visual Studio

Install the latest version of Visual Studio (https://visualstudio.microsoft.com/downloads/) with the Desktop Development for C++ Workflow. To add the workflow, follow the instructions linked below: -https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify.

Python

Install Python. For new Python users, we recommend installing via Anaconda: https://docs.anaconda.com/anaconda/install/windows/

Node.js

Install Node.js: https://nodejs.org/en/download/

Git bash

Install git bash: https://git-scm.com/downloads

Note: restart computer after all installs are complete

- - +https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify.

Python

Install Python. For new Python users, we recommend installing via Anaconda: https://docs.anaconda.com/anaconda/install/windows/

Node.js

Install Node.js: https://nodejs.org/en/download/

Git bash

Install git bash: https://git-scm.com/downloads

Note: restart computer after all installs are complete

+ + \ No newline at end of file diff --git a/docs/1.1.0/troubleshooting/index.html b/docs/1.1.0/troubleshooting/index.html index 0d2779cf..8a677db0 100644 --- a/docs/1.1.0/troubleshooting/index.html +++ b/docs/1.1.0/troubleshooting/index.html @@ -3,14 +3,14 @@ -Troubleshooting | Honeycomb - - +Troubleshooting | Honeycomb + +
-
Version: 1.1.0

Troubleshooting

When developing electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The react app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

Potential Issues

Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild.

- - +
Version: 1.1.0

Troubleshooting

When developing electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The react app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

Potential Issues

Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild.

+ + \ No newline at end of file diff --git a/docs/1.1.0/version_control/index.html b/docs/1.1.0/version_control/index.html index 96e809b1..10add074 100644 --- a/docs/1.1.0/version_control/index.html +++ b/docs/1.1.0/version_control/index.html @@ -3,14 +3,14 @@ -Version Control | Honeycomb - - +Version Control | Honeycomb + +
-
Version: 1.1.0

Version Control

Git Overview

Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

Git creates a hidden .git folder (in the current folder) to store the details of the file system - this folder contains all the data required to track your files and is known as a repository, or repo.

Git tracks file changes by the user creating a save point, or in Git terms a commit. Each commit takes a snapshot of the current file system. Commits are uniquely identified by a SHA–1 hash. This is a 40 character string which may along the lines of ded7a0db6422d59e9893e975e32275fc36f853daThis hash can be used to track a particular commit within the repository.

Nearly all operations that are performed by Git are in you local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below. In summary, a typical flow consists of making changes to your files, staging them via git add, marking a save point via git commit, then finally syncing to your remote (e.g., GitHub) via git push. If you are pushing changes to your remote from multiple places, you can bring changes your most recent version using git pull, which is the equivalent of doing git fetch followed by a git merge operation

Cheatsheet

CommandBrief
git add <files>add a file to next commit (stage)
git commit -m <message>commit staged files
git pushupload staged commit to repo
git pullget remote repo commits and download (try and resolve conflicts)
git clone <url>download entire repository

Best Practices

Workflow

We recommend a simple flow based on following rules:

  • Use topic/feature branches, no direct commits on main.
  • Perform tests and code reviews before merges into main, not afterwards.
  • Everyone starts from main, and targets main.
  • Commit messages reflect intent.

Branches

  • main is the default branch and where releases are made off. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches
  • topic branches are created for new features, fixes, or really any changes

Comment styles

We encourage using Commitizen, a great tool for writing angular commits - this will create a standardized commit format which makes for easier change logging and more sane messages.

- - +
Version: 1.1.0

Version Control

Git Overview

Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

Git creates a hidden .git folder (in the current folder) to store the details of the file system - this folder contains all the data required to track your files and is known as a repository, or repo.

Git tracks file changes by the user creating a save point, or in Git terms a commit. Each commit takes a snapshot of the current file system. Commits are uniquely identified by a SHA–1 hash. This is a 40 character string which may along the lines of ded7a0db6422d59e9893e975e32275fc36f853daThis hash can be used to track a particular commit within the repository.

Nearly all operations that are performed by Git are in you local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below. In summary, a typical flow consists of making changes to your files, staging them via git add, marking a save point via git commit, then finally syncing to your remote (e.g., GitHub) via git push. If you are pushing changes to your remote from multiple places, you can bring changes your most recent version using git pull, which is the equivalent of doing git fetch followed by a git merge operation

Cheatsheet

CommandBrief
git add <files>add a file to next commit (stage)
git commit -m <message>commit staged files
git pushupload staged commit to repo
git pullget remote repo commits and download (try and resolve conflicts)
git clone <url>download entire repository

Best Practices

Workflow

We recommend a simple flow based on following rules:

  • Use topic/feature branches, no direct commits on main.
  • Perform tests and code reviews before merges into main, not afterwards.
  • Everyone starts from main, and targets main.
  • Commit messages reflect intent.

Branches

  • main is the default branch and where releases are made off. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches
  • topic branches are created for new features, fixes, or really any changes

Comment styles

We encourage using Commitizen, a great tool for writing angular commits - this will create a standardized commit format which makes for easier change logging and more sane messages.

+ + \ No newline at end of file diff --git a/docs/2.x/ci/index.html b/docs/2.x/ci/index.html index 15af6fe4..42a32c00 100644 --- a/docs/2.x/ci/index.html +++ b/docs/2.x/ci/index.html @@ -3,14 +3,14 @@ -Automated Builds | Honeycomb - - +Automated Builds | Honeycomb + +
-
Version: 2.x

Automated Builds

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD:

Continuous Integration, Continuous Deployment: CI/CD or CICD refers to continuous integration and either continuous delivery or continuous deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

GitHub Actions are written as YML files inside a .github/worflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows. Mac and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds PsiTurk version when linux or all operating systems are selected
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage on private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their [official documentation](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions).

Github Actions for firebase hosting

Automatic deployment on a firebase hosting site can also be setup with github actions. Before proceeding with the follwing steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase

  • Run firebase init hosting:github in the terminal and follow the CLI prompts to start setting up the github actions.
    • For the github directory question, select your task github directory.
    • When prompted with the npm command, type npm install && npm run build:firebase

There should be two new .yml files, firebase-hosting-pull-request.yml and firebase-hosting-merge.yml, created in the .github/workflows directory for a deployment preview for each pull request and the official deployment when merged onto the main branch.

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file, install and run.

The executable does not require installation of any additional software.

Uninstall the task

Windows

Go to System Settings: Add or remove programs. Look for the name of your task in the installed programs list, and uninstall.

- - +
Version: 2.x

Automated Builds

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD:

Continuous Integration, Continuous Deployment: CI/CD or CICD refers to continuous integration and either continuous delivery or continuous deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

GitHub Actions are written as YML files inside a .github/worflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows. Mac and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds PsiTurk version when linux or all operating systems are selected
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage on private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their [official documentation](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions).

Github Actions for firebase hosting

Automatic deployment on a firebase hosting site can also be setup with github actions. Before proceeding with the follwing steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase

  • Run firebase init hosting:github in the terminal and follow the CLI prompts to start setting up the github actions.
    • For the github directory question, select your task github directory.
    • When prompted with the npm command, type npm install && npm run build:firebase

There should be two new .yml files, firebase-hosting-pull-request.yml and firebase-hosting-merge.yml, created in the .github/workflows directory for a deployment preview for each pull request and the official deployment when merged onto the main branch.

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file, install and run.

The executable does not require installation of any additional software.

Uninstall the task

Windows

Go to System Settings: Add or remove programs. Look for the name of your task in the installed programs list, and uninstall.

+ + \ No newline at end of file diff --git a/docs/2.x/configuration/index.html b/docs/2.x/configuration/index.html index 2414d544..e2b9e2d9 100644 --- a/docs/2.x/configuration/index.html +++ b/docs/2.x/configuration/index.html @@ -3,14 +3,14 @@ -Configuration | Honeycomb - - +Configuration | Honeycomb + +
-
Version: 2.x

Configuration

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate whether they are mandatory, optional and needed during build (npm build) or run time (using the application executable or npm run dev)

  • ELECTRON_START_URL stringoptional: URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode.
  • EVENT_MARKER_PRODUCT_IDstringoptionalruntime: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME stringoptionalruntime: The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_VOLUMEbooleandefault falsebuildtime: whether the participant is being asked to adjust volume. This can be used on both the desktop (electron) and online settings.
  • REACT_APP_VIDEObooleandefault falsebuildtime: whether the participant is being video recorded. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_EEGbooleandefault falsebuildtime: whether the event marker/EEG is available. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_PHOTODIODEbooleandefault falsebuildtime: whether the photodiode is in use. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_PARTICIPANT_ID stringoptionalruntime: The default participant id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.
  • REACT_APP_STUDY_ID stringoptionalruntime: The default study id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.

Here are details on some of the badges:

  • runtime: Run-time environment variable. Set at the system level. See this tutorial for OS specific instructions.

  • buildtime: Build-time environment variable. Set in a .env file before building. Can also be defined in a separate file under the env/ directory and called with the dotenv-cli before building. NOTE: The dotenv command will not work directly from the command line. Instead, to set build-time environment variables, either run an existing npm script (e.g., npm run build:clinic, which sets clinic variables) or add a new script to package.json with the following format:

"[build|dev]:<script name>": "dotenv -e env/<your env file> npm run [build|dev]"

Or, to add your new variables to an existing environment configuration, e.g. .env.clinic, create a script in the following format:

"[build|dev]:<script name>": "dotenv -e env/<your env file> npm run [build|dev]:clinic"

Then run the script like so: npm run [build|dev]:<script name>.

- - +
Version: 2.x

Configuration

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate whether they are mandatory, optional and needed during build (npm build) or run time (using the application executable or npm run dev)

  • ELECTRON_START_URL stringoptional: URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode.
  • EVENT_MARKER_PRODUCT_IDstringoptionalruntime: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME stringoptionalruntime: The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_VOLUMEbooleandefault falsebuildtime: whether the participant is being asked to adjust volume. This can be used on both the desktop (electron) and online settings.
  • REACT_APP_VIDEObooleandefault falsebuildtime: whether the participant is being video recorded. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_EEGbooleandefault falsebuildtime: whether the event marker/EEG is available. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_PHOTODIODEbooleandefault falsebuildtime: whether the photodiode is in use. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_PARTICIPANT_ID stringoptionalruntime: The default participant id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.
  • REACT_APP_STUDY_ID stringoptionalruntime: The default study id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.

Here are details on some of the badges:

  • runtime: Run-time environment variable. Set at the system level. See this tutorial for OS specific instructions.

  • buildtime: Build-time environment variable. Set in a .env file before building. Can also be defined in a separate file under the env/ directory and called with the dotenv-cli before building. NOTE: The dotenv command will not work directly from the command line. Instead, to set build-time environment variables, either run an existing npm script (e.g., npm run build:clinic, which sets clinic variables) or add a new script to package.json with the following format:

"[build|dev]:<script name>": "dotenv -e env/<your env file> npm run [build|dev]"

Or, to add your new variables to an existing environment configuration, e.g. .env.clinic, create a script in the following format:

"[build|dev]:<script name>": "dotenv -e env/<your env file> npm run [build|dev]:clinic"

Then run the script like so: npm run [build|dev]:<script name>.

+ + \ No newline at end of file diff --git a/docs/2.x/event_triggers/index.html b/docs/2.x/event_triggers/index.html index 14b25f98..31e84934 100644 --- a/docs/2.x/event_triggers/index.html +++ b/docs/2.x/event_triggers/index.html @@ -3,16 +3,16 @@ -Set up event triggers | Honeycomb - - +Set up event triggers | Honeycomb + +
-
Version: 2.x

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set to the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here: https://github.com/neuromotion/USB-event-marker +

Version: 2.x

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set to the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here: https://github.com/neuromotion/USB-event-marker Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

Send event code triggers

Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from -./trigger and export as eventCodes

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncodewith the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

- - +./trigger and export as eventCodes

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncodewith the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

+ + \ No newline at end of file diff --git a/docs/2.x/firebase/index.html b/docs/2.x/firebase/index.html index a087b01e..f5dd4184 100644 --- a/docs/2.x/firebase/index.html +++ b/docs/2.x/firebase/index.html @@ -3,14 +3,14 @@ -Set up Firebase | Honeycomb - - +Set up Firebase | Honeycomb + +
-
Version: 2.x

Set up Firebase

Honeycomb comes with methods and configurations for easy Firebase and Cloud Firestore set up. Please use this section to configure Firebase Hosting services and firestore cloud storage.

Getting Started

Follow these steps to create a firebase project and link it with the current task.

1. Initializing firebase account and project

  • Create and login to a firebase account on the Firebase website.
  • Create a firebase project by clicking add project and enter a Project Name.

2. Linking firebase to task

  • Install Firebase CLI on your local computer.
  • Login to firebase using firebase login command in the terminal.
  • Navigate to the .firebaserc file home directory and edit the "default" field with the project name given in part 1.
    {
    "projects": {
    "default": "<your project name>"
    }
    }

3. Copying web app credentials.

  • Navigate to the firebase console and select the project.
  • Create a new Web App by clicking on Add App or the </> code symbol and following the prompts.
  • Enter the a name for the Firebase app (could be the same as your Honeycomb task repo name).
  • Check "Also set up Firebase Hosting for this app."
  • Click Register App. This should auto-generate a script with several values that you need to copy into the next step.
  • Copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo:
      REACT_APP_apiKey=
    REACT_APP_authDomain=
    REACT_APP_projectId=
    REACT_APP_storageBucket=
    REACT_APP_messagingSenderId=
    REACT_APP_appId=
  • You can skip running firebase init if prompted to do so. The results of firebase init are already saved into the Honeycomb template repo.

Firebase is now set up!

Setting up firestore.

Honeycomb includes cloud storage for task data using Firestore. Follow these steps to initialize firestore:

  • Navigate to the current project in the developer console and select Firestore Database from the sidebar.
  • Click Create Database, select production mode and choose the current location for the cloud storage bucket.

Firestore security rules.

Firestore Security Rules provides easy server-side authorization to the database. For a honeycomb task, we use the security rules to allow access to only authorized participants for a specified study. Honeycomb's default set of rules is included in the firestore.rules file in the home directory. This file can be edited to change the rules. To deploy the rules in the file, type the following line of code in the terminal:

firebase deploy --only firestore:rules

Alternatively, Editing the rules directly in the console is also possible. To do so, navigate to the Rules tab in the Firestore Database section from the firebase console sidebar then copy and paste the code that is in the firestore.rules file.

Firestore database and rules are now both deployed. For Honeycomb's default set of rules, to add an authorized participant for a study, create a collection named registered_studies, add a study with the study ID as the document name in that collection. For each registered study, add an array field named registered_participants where each element in the array will be an authorized participant for that study.

- - +
Version: 2.x

Set up Firebase

Honeycomb comes with methods and configurations for easy Firebase and Cloud Firestore set up. Please use this section to configure Firebase Hosting services and firestore cloud storage.

Getting Started

Follow these steps to create a firebase project and link it with the current task.

1. Initializing firebase account and project

  • Create and login to a firebase account on the Firebase website.
  • Create a firebase project by clicking add project and enter a Project Name.

2. Linking firebase to task

  • Install Firebase CLI on your local computer.
  • Login to firebase using firebase login command in the terminal.
  • Navigate to the .firebaserc file home directory and edit the "default" field with the project name given in part 1.
    {
    "projects": {
    "default": "<your project name>"
    }
    }

3. Copying web app credentials.

  • Navigate to the firebase console and select the project.
  • Create a new Web App by clicking on Add App or the </> code symbol and following the prompts.
  • Enter the a name for the Firebase app (could be the same as your Honeycomb task repo name).
  • Check "Also set up Firebase Hosting for this app."
  • Click Register App. This should auto-generate a script with several values that you need to copy into the next step.
  • Copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo:
      REACT_APP_apiKey=
    REACT_APP_authDomain=
    REACT_APP_projectId=
    REACT_APP_storageBucket=
    REACT_APP_messagingSenderId=
    REACT_APP_appId=
  • You can skip running firebase init if prompted to do so. The results of firebase init are already saved into the Honeycomb template repo.

Firebase is now set up!

Setting up firestore.

Honeycomb includes cloud storage for task data using Firestore. Follow these steps to initialize firestore:

  • Navigate to the current project in the developer console and select Firestore Database from the sidebar.
  • Click Create Database, select production mode and choose the current location for the cloud storage bucket.

Firestore security rules.

Firestore Security Rules provides easy server-side authorization to the database. For a honeycomb task, we use the security rules to allow access to only authorized participants for a specified study. Honeycomb's default set of rules is included in the firestore.rules file in the home directory. This file can be edited to change the rules. To deploy the rules in the file, type the following line of code in the terminal:

firebase deploy --only firestore:rules

Alternatively, Editing the rules directly in the console is also possible. To do so, navigate to the Rules tab in the Firestore Database section from the firebase console sidebar then copy and paste the code that is in the firestore.rules file.

Firestore database and rules are now both deployed. For Honeycomb's default set of rules, to add an authorized participant for a study, create a collection named registered_studies, add a study with the study ID as the document name in that collection. For each registered study, add an array field named registered_participants where each element in the array will be an authorized participant for that study.

+ + \ No newline at end of file diff --git a/docs/2.x/folders/index.html b/docs/2.x/folders/index.html index c86402d5..14834854 100644 --- a/docs/2.x/folders/index.html +++ b/docs/2.x/folders/index.html @@ -3,14 +3,14 @@ -Project Organization | Honeycomb - - +Project Organization | Honeycomb + +
-
Version: 2.x

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used (and definitely not mutated), and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code. Below are descriptions of the main files and folders.

package.json

The package.json file contains metadata about your project and scripts to run tasks related to your task. The name should be updated to your task's name and scripts can be added as desired, but otherwise this file should not be edited manually. To remove or add a dependency use npm install or npm uninstall with the -D flag if installing a dev dependency.

The package-lock.json contains metadata about the package installation. It should never be manually updated.

assets/

The icons used for the installed applications are put here.

env/

This folder contains different .env files with presets for common use cases. These files can be loaded with dotenv, which is explained in greater detail in the Configuration section.

public/

The public directory contains files that are used as assets in the built app. The favicon.ico is the small icon you can see in the browser tab (on Chrome) - it is set to Brown's logo in the project. The index.html contains the shell of your website - the name displayed on the tab can be changed here, otherwise it shouldn't need to be edited. The scripts included in the file are for psiturk as are the files in the lib/ directory.

electron.js

This file contains all of the code relating to the electron app. This includes the event-marker, throwing errors via dialog windows, saving data, and reading files.

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes.

Note: the productId can be overwritten by the environment variable EVENT_MARKER_PRODUCT_ID

src/

This folder contains the code for the app, the vast majority of changes and code should go here.

App.jsx

This is the starting point for the app. The <Login> component handles user authentication in the different use cases and the <JsPsychExperiment> component initializes the jspsych experiment. This is also where communication is set up with the electron and psiturk processes.

App.css

This is where styling for the app is housed. If colors, fonts, spacing, etc. need to be set, do it here.

assets/

This folder contains any static files that are used by the app, such as images.

components/

This folder contains the components referenced in App.jsx.

config/

In the config/ directory, there are .js files which contain settings for the different parts of the task. Every task should have a main config and a trigger config (assuming use of the event marker). The main config has all global settings for the task (such as whether it is in mturk mode or not), load the appropriate language file, and set up a default (or only) configuration object for the task. Different in-task features can be loaded from .env files and is set in the main config. For example, we have included some of these files in the env directory (e.g. env.clinic file enables event marker, photodiode and volume adjustment). The trigger config has settings specific to the event marker and uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) as well as allows for mturk specific language. This also makes it easy to re-use common phrases in many places in the task.

lib/

The lib/ directory contains utility functions and markup that is used in the tasks. This allows for functions and html to be re-used wherever needed. The lib/utils.js file contains functions that are generally useful across many tasks, whereas lib/taskUtils.js contains functions specific to this task.

lib/markup

markup files should contain primarily templates for HTML that is used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

timelines

jspsych uses timelines to control what trials are displayed in what order. timelines can contain other timelines, which is why there may be several files in this directory. The main.js file should have the timeline that is called by App.jsx in the <JsPsychExperiment> component.

trials

jspsych uses trials as its base unit of an experiment. These trials do things such as display some stimulus or request a response.

- - +
Version: 2.x

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used (and definitely not mutated), and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code. Below are descriptions of the main files and folders.

package.json

The package.json file contains metadata about your project and scripts to run tasks related to your task. The name should be updated to your task's name and scripts can be added as desired, but otherwise this file should not be edited manually. To remove or add a dependency use npm install or npm uninstall with the -D flag if installing a dev dependency.

The package-lock.json contains metadata about the package installation. It should never be manually updated.

assets/

The icons used for the installed applications are put here.

env/

This folder contains different .env files with presets for common use cases. These files can be loaded with dotenv, which is explained in greater detail in the Configuration section.

public/

The public directory contains files that are used as assets in the built app. The favicon.ico is the small icon you can see in the browser tab (on Chrome) - it is set to Brown's logo in the project. The index.html contains the shell of your website - the name displayed on the tab can be changed here, otherwise it shouldn't need to be edited. The scripts included in the file are for psiturk as are the files in the lib/ directory.

electron.js

This file contains all of the code relating to the electron app. This includes the event-marker, throwing errors via dialog windows, saving data, and reading files.

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes.

Note: the productId can be overwritten by the environment variable EVENT_MARKER_PRODUCT_ID

src/

This folder contains the code for the app, the vast majority of changes and code should go here.

App.jsx

This is the starting point for the app. The <Login> component handles user authentication in the different use cases and the <JsPsychExperiment> component initializes the jspsych experiment. This is also where communication is set up with the electron and psiturk processes.

App.css

This is where styling for the app is housed. If colors, fonts, spacing, etc. need to be set, do it here.

assets/

This folder contains any static files that are used by the app, such as images.

components/

This folder contains the components referenced in App.jsx.

config/

In the config/ directory, there are .js files which contain settings for the different parts of the task. Every task should have a main config and a trigger config (assuming use of the event marker). The main config has all global settings for the task (such as whether it is in mturk mode or not), load the appropriate language file, and set up a default (or only) configuration object for the task. Different in-task features can be loaded from .env files and is set in the main config. For example, we have included some of these files in the env directory (e.g. env.clinic file enables event marker, photodiode and volume adjustment). The trigger config has settings specific to the event marker and uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) as well as allows for mturk specific language. This also makes it easy to re-use common phrases in many places in the task.

lib/

The lib/ directory contains utility functions and markup that is used in the tasks. This allows for functions and html to be re-used wherever needed. The lib/utils.js file contains functions that are generally useful across many tasks, whereas lib/taskUtils.js contains functions specific to this task.

lib/markup

markup files should contain primarily templates for HTML that is used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

timelines

jspsych uses timelines to control what trials are displayed in what order. timelines can contain other timelines, which is why there may be several files in this directory. The main.js file should have the timeline that is called by App.jsx in the <JsPsychExperiment> component.

trials

jspsych uses trials as its base unit of an experiment. These trials do things such as display some stimulus or request a response.

+ + \ No newline at end of file diff --git a/docs/2.x/index.html b/docs/2.x/index.html index 422195df..a36d0544 100644 --- a/docs/2.x/index.html +++ b/docs/2.x/index.html @@ -3,14 +3,14 @@ -Introduction | Honeycomb - - +Introduction | Honeycomb + +
-
Version: 2.x

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy to install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

- - +
Version: 2.x

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy to install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

+ + \ No newline at end of file diff --git a/docs/2.x/npm_scripts/index.html b/docs/2.x/npm_scripts/index.html index d68b3f20..5a624596 100644 --- a/docs/2.x/npm_scripts/index.html +++ b/docs/2.x/npm_scripts/index.html @@ -3,15 +3,15 @@ -NPM Scripts | Honeycomb - - +NPM Scripts | Honeycomb + +
-
Version: 2.x

NPM Scripts

In the project directory, you can run:

npm run dev

Runs npm start and npm run electron-dev concurrently. This may not play nicely with windows. If it doesn't, run npm start and npm run electron-dev from different terminal windows.

npm start

Runs the app in the development mode.

Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.

See the section about running tests for more information.

npm build

Creates a production build of the app (renderer). This must be done before running package:platform or the psiturk build instructions.

npm run package:platform

It correctly bundles creates electron packages for the given platform. It then creates an installer for that platform. The output can be found in /dist -platforms: windows, mac, linux.

Prerequisites

If not running this command on a windows machine, must have mono and wine installed.

npm run eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Run Electron

npm run electron

Run the built app.

npm run electron-dev

Run the current state of the code (un-built).

- - +
Version: 2.x

NPM Scripts

In the project directory, you can run:

npm run dev

Runs npm start and npm run electron-dev concurrently. This may not play nicely with windows. If it doesn't, run npm start and npm run electron-dev from different terminal windows.

npm start

Runs the app in the development mode.

Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.

See the section about running tests for more information.

npm build

Creates a production build of the app (renderer). This must be done before running package:platform or the psiturk build instructions.

npm run package:platform

It correctly bundles creates electron packages for the given platform. It then creates an installer for that platform. The output can be found in /dist +platforms: windows, mac, linux.

Prerequisites

If not running this command on a windows machine, must have mono and wine installed.

npm run eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Run Electron

npm run electron

Run the built app.

npm run electron-dev

Run the current state of the code (un-built).

+ + \ No newline at end of file diff --git a/docs/2.x/online_integration/index.html b/docs/2.x/online_integration/index.html index 7a600989..c8e4b8ff 100644 --- a/docs/2.x/online_integration/index.html +++ b/docs/2.x/online_integration/index.html @@ -3,18 +3,18 @@ -Deploy online | Honeycomb - - +Deploy online | Honeycomb + +
-
Version: 2.x

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a psiturk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. +

Version: 2.x

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a psiturk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

  • Build the application: npm run build

  • Move to the psiturkit directory: cd psiturkit

  • If it's the first time you're running the script:
    ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>

  • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):
    ./psiturk-it -u -p <PATH_TO_NEW_PSITURK_PROJECT>

Running psiturk

After that, just navigate to your newly created PsiTurk project directory.

shell> psiturk #start psiturk
psiturk> server on #start server
psiturk> debug #debug mode

Running on the Web

Using Github Pages

Running npm run build generates static content into the build directory that can be served using any static contents hosting service. The workflow .github/workflows/release-home-all.yml uploads the build directory to the gh-branch to serve the application on GitHub pages as an example. After a creating a tag, the workflow will run and your application will be served at <githubuser>.github.io/<repository>. -For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.
  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.
  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.
  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.
  5. To create the secret copy your private key e.g. xclip -sel clip < ~/.ssh/id_rsa and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.
  6. Make sure the publishing source for your repository is configured for gh-pages branch.

Using Firebase

We have included methods and configurations for close integration with firebase. Before proceeding with the follwing steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase.

  1. Run npm run build:firebase in the terminal to create a production build for firebase.
  2. Run firebase deploy in the terminal to deploy the production build.
  3. The production build is now deployed to the firebase project domain.

To automate firebase deployments, we have included instructions on setting up firebase github actions on our Automated Builds page

- - +For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.
  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.
  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.
  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.
  5. To create the secret copy your private key e.g. xclip -sel clip < ~/.ssh/id_rsa and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.
  6. Make sure the publishing source for your repository is configured for gh-pages branch.

Using Firebase

We have included methods and configurations for close integration with firebase. Before proceeding with the follwing steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase.

  1. Run npm run build:firebase in the terminal to create a production build for firebase.
  2. Run firebase deploy in the terminal to deploy the production build.
  3. The production build is now deployed to the firebase project domain.

To automate firebase deployments, we have included instructions on setting up firebase github actions on our Automated Builds page

+ + \ No newline at end of file diff --git a/docs/2.x/quick_start/index.html b/docs/2.x/quick_start/index.html index fc0b6ff4..8de88886 100644 --- a/docs/2.x/quick_start/index.html +++ b/docs/2.x/quick_start/index.html @@ -3,13 +3,13 @@ -Quick Start | Honeycomb - - +Quick Start | Honeycomb + +
-
Version: 2.x

Quick Start

To start a new task locally, in development mode follow these steps:

1. Start your new task from our template repository

The simplest way to get started is creating a new repository using Honeycomb as a template.

Go to https://github.com/brown-ccv/honeycomb and click on Use this template on the top right. Then select the organization and the name of your repository and click on create repository from template

Alternatively, you can use GitHub CLI to create a new project based on the Honeycomb template repository. First, install GitHub CLI (https://cli.github.com/), then simply run on your terminal:

gh repo create your-new-task-name --template brown-ccv/honeycomb

You can now move into the directory that was just created

cd your-new-task-name

2. Change name and description

Update the package.json fields to reflect your app name and description, e.g. name, author, repository

3. Install the dependencies.

Electron Dependencies +

Version: 2.x

Quick Start

To start a new task locally, in development mode follow these steps:

1. Start your new task from our template repository

The simplest way to get started is creating a new repository using Honeycomb as a template.

Go to https://github.com/brown-ccv/honeycomb and click on Use this template on the top right. Then select the organization and the name of your repository and click on create repository from template

Alternatively, you can use GitHub CLI to create a new project based on the Honeycomb template repository. First, install GitHub CLI (https://cli.github.com/), then simply run on your terminal:

gh repo create your-new-task-name --template brown-ccv/honeycomb

You can now move into the directory that was just created

cd your-new-task-name

2. Change name and description

Update the package.json fields to reflect your app name and description, e.g. name, author, repository

3. Install the dependencies.

Electron Dependencies Honeycomb relies on Electron to package the cross-platform desktop applications. Before starting, you will need to install Electron's pre-requisites below. You can find the full instructions on the electron documentation for your specific OS.

Windows

  • Visual Studio: Install the latest version of Visual Studio with the Desktop Development for C++ Workflow. To add the workflow, follow these instructions.

  • Node.js: @@ -25,8 +25,8 @@ Follow installation instructions on the electron docs

Honeycomb npm packages Once Node.js is installed you will able to use npm commands in the terminal. To install the dependencies for HoneyComb run the following command at the terminal (remember you need cd your-new-task-name before)

npm install

4. Run the task in dev mode

To launch an electron window with the task with the inspector open to the console and will hot-reload when changes are made to the app

  • For Mac and Linux:

    npm run dev
  • For Windows: You will need to open 2 terminals. In the first -and make sure you are in the task-<TASK NAME> repo directory- run the command:

    npm start

    In the second terminal - make sure you are in the task-<TASK NAME> repo directory-, run:

    npm run electron-dev

5. Run the task with preset environment variables

We have provided various .env files and npm scripts to run the task in common settings like home or clinic. Here are the possible commands:

npm run dev:home
npm run dev:home:video
npm run dev:clinic
npm run dev:clinic:video
npm run dev:firebase

6. Check out the data

The data is saved throughout the task to the users's app directory. This is logged at the beginning of the task wherever you ran npm run dev (for windows, instead in two different terminals ran npm start and npm run electron-dev). It is also stored in a folder that is generated by the app, which should be found on the desktop.

7. Quit The Task

If you want to quit in the middle of the task, you can use these keyboard shortcuts:

Ctrl+W (for PC/Windows)
Cmd+Q (for Mac)

Partial data will be saved.

7. Merge updates from honeycomb template repo

Honeycomb is an active project, and will be updated with new features over time. To merge the honeycomb template repository updates with your task, follow the following steps: -First time only:

git remote add honeycomb https://github.com/brown-ccv/honeycomb.git

Every time:

git fetch --all
git merge honeycomb/main --allow-unrelated histories

If there are any conflicts:

git stash

To merge:

git commit -a -m "merge honeycomb latest"

8. Run automated tests

When getting started, merging updates, or making custom changes, it's a good idea to run automated tests. These can tell you if things are working or if recent changes broke something that previously worked.

To run the tests interactively:

npm test

Or non-interactively:

CI=true npm test

Linux

When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runer creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

This is a "known issue" with some test runners on Linux, as in discussions here and here.

One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

  • Command that initially fails with ENOSPC: npm test
  • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
  • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
  • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
  • Save, exit, and reload the config file: sudo sysctl -p
  • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
  • Retry the initial command, which should now succeed: npm test
- - +First time only:

git remote add honeycomb https://github.com/brown-ccv/honeycomb.git

Every time:

git fetch --all
git merge honeycomb/main --allow-unrelated histories

If there are any conflicts:

git stash

To merge:

git commit -a -m "merge honeycomb latest"

8. Run automated tests

When getting started, merging updates, or making custom changes, it's a good idea to run automated tests. These can tell you if things are working or if recent changes broke something that previously worked.

To run the tests interactively:

npm test

Or non-interactively:

CI=true npm test

Linux

When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runer creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

This is a "known issue" with some test runners on Linux, as in discussions here and here.

One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

  • Command that initially fails with ENOSPC: npm test
  • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
  • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
  • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
  • Save, exit, and reload the config file: sudo sysctl -p
  • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
  • Retry the initial command, which should now succeed: npm test
+ + \ No newline at end of file diff --git a/docs/2.x/software_prerecs/index.html b/docs/2.x/software_prerecs/index.html index 69540371..0c463373 100644 --- a/docs/2.x/software_prerecs/index.html +++ b/docs/2.x/software_prerecs/index.html @@ -3,16 +3,16 @@ -Software Prerequisites | Honeycomb - - +Software Prerequisites | Honeycomb + +
-
Version: 2.x

Software Prerequisites

Windows

Visual Studio

Install the latest version of Visual Studio (https://visualstudio.microsoft.com/downloads/) with the Desktop Development for C++ Workflow. +

Version: 2.x

Software Prerequisites

Windows

Visual Studio

Install the latest version of Visual Studio (https://visualstudio.microsoft.com/downloads/) with the Desktop Development for C++ Workflow. To add the workflow, follow the instructions linked below: -https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify.

Python

Install Python. For new Python users, we recommend installing via Anaconda: https://docs.anaconda.com/anaconda/install/windows/

Node.js

Install Node.js: https://nodejs.org/en/download/

Git bash

Install git bash: https://git-scm.com/downloads

Note: restart computer after all installs are complete

- - +https://docs.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-160#:~:text=If%20you%20have%20Visual%20Studio,Then%2C%20choose%20Modify.

Python

Install Python. For new Python users, we recommend installing via Anaconda: https://docs.anaconda.com/anaconda/install/windows/

Node.js

Install Node.js: https://nodejs.org/en/download/

Git bash

Install git bash: https://git-scm.com/downloads

Note: restart computer after all installs are complete

+ + \ No newline at end of file diff --git a/docs/2.x/troubleshooting/index.html b/docs/2.x/troubleshooting/index.html index e20cdb42..8239744d 100644 --- a/docs/2.x/troubleshooting/index.html +++ b/docs/2.x/troubleshooting/index.html @@ -3,14 +3,14 @@ -Troubleshooting | Honeycomb - - +Troubleshooting | Honeycomb + +
-
Version: 2.x

Troubleshooting

When developing electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The react app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

Potential Issues

Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild.

Inspecting Errors

In case you want to find out where the error is coming from when running the app locally:

  • Try reviewing logs in the terminal
  • Inspect element in your browser by openning your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.
- - +
Version: 2.x

Troubleshooting

When developing electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The react app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

Potential Issues

Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild.

Inspecting Errors

In case you want to find out where the error is coming from when running the app locally:

  • Try reviewing logs in the terminal
  • Inspect element in your browser by openning your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.
+ + \ No newline at end of file diff --git a/docs/2.x/version_control/index.html b/docs/2.x/version_control/index.html index 5d672016..ee7545bd 100644 --- a/docs/2.x/version_control/index.html +++ b/docs/2.x/version_control/index.html @@ -3,14 +3,14 @@ -Version Control | Honeycomb - - +Version Control | Honeycomb + +
-
Version: 2.x

Version Control

Git Overview

Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

Git creates a hidden .git folder (in the current folder) to store the details of the file system - this folder contains all the data required to track your files and is known as a repository, or repo.

Git tracks file changes by the user creating a save point, or in Git terms a commit. Each commit takes a snapshot of the current file system. Commits are uniquely identified by a SHA–1 hash. This is a 40 character string which may along the lines of ded7a0db6422d59e9893e975e32275fc36f853daThis hash can be used to track a particular commit within the repository.

Nearly all operations that are performed by Git are in you local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below. In summary, a typical flow consists of making changes to your files, staging them via git add, marking a save point via git commit, then finally syncing to your remote (e.g., GitHub) via git push. If you are pushing changes to your remote from multiple places, you can bring changes your most recent version using git pull, which is the equivalent of doing git fetch followed by a git merge operation

Cheatsheet

CommandBrief
git add <files>add a file to next commit (stage)
git commit -m <message>commit staged files
git pushupload staged commit to repo
git pullget remote repo commits and download (try and resolve conflicts)
git clone <url>download entire repository

Best Practices

Workflow

We recommend a simple flow based on following rules:

  • Use topic/feature branches, no direct commits on main.
  • Perform tests and code reviews before merges into main, not afterwards.
  • Everyone starts from main, and targets main.
  • Commit messages reflect intent.

Branches

  • main is the default branch and where releases are made off. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches
  • topic branches are created for new features, fixes, or really any changes

Comment styles

We encourage using Commitizen, a great tool for writing angular commits - this will create a standardized commit format which makes for easier change logging and more sane messages.

- - +
Version: 2.x

Version Control

Git Overview

Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

Git creates a hidden .git folder (in the current folder) to store the details of the file system - this folder contains all the data required to track your files and is known as a repository, or repo.

Git tracks file changes by the user creating a save point, or in Git terms a commit. Each commit takes a snapshot of the current file system. Commits are uniquely identified by a SHA–1 hash. This is a 40 character string which may along the lines of ded7a0db6422d59e9893e975e32275fc36f853daThis hash can be used to track a particular commit within the repository.

Nearly all operations that are performed by Git are in you local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below. In summary, a typical flow consists of making changes to your files, staging them via git add, marking a save point via git commit, then finally syncing to your remote (e.g., GitHub) via git push. If you are pushing changes to your remote from multiple places, you can bring changes your most recent version using git pull, which is the equivalent of doing git fetch followed by a git merge operation

Cheatsheet

CommandBrief
git add <files>add a file to next commit (stage)
git commit -m <message>commit staged files
git pushupload staged commit to repo
git pullget remote repo commits and download (try and resolve conflicts)
git clone <url>download entire repository

Best Practices

Workflow

We recommend a simple flow based on following rules:

  • Use topic/feature branches, no direct commits on main.
  • Perform tests and code reviews before merges into main, not afterwards.
  • Everyone starts from main, and targets main.
  • Commit messages reflect intent.

Branches

  • main is the default branch and where releases are made off. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches
  • topic branches are created for new features, fixes, or really any changes

Comment styles

We encourage using Commitizen, a great tool for writing angular commits - this will create a standardized commit format which makes for easier change logging and more sane messages.

+ + \ No newline at end of file diff --git a/docs/3.0.0/ci/index.html b/docs/3.0.0/ci/index.html index 6d03311f..52d2639d 100644 --- a/docs/3.0.0/ci/index.html +++ b/docs/3.0.0/ci/index.html @@ -3,14 +3,14 @@ -Automated Builds | Honeycomb - - +Automated Builds | Honeycomb + +
-
Version: 3.0.0

Automated Builds

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD?

CI/CD refers to Continuous Integration and either Continuous Delivery or Continuous Deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

GitHub Actions are written as YML files inside a .github/worflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows. Mac and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds PsiTurk version when linux or all operating systems are selected
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage on private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their [official documentation](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions).

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file, install and run.

The executable does not require installation of any additional software.

Uninstall the task

Windows

Go to System Settings: Add or remove programs. Look for the name of your task in the installed programs list, and Uninstall.

The executable does not require installation of any additional software.

Firebase Hosting

Automatic deployment on a firebase hosting site can also be setup with github actions. Before proceeding with the following steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase. Then run the following command in the terminal:

firebase init hosting:github
  • Be sure to type "<username>/<repository name>" exactly as it appears in GitHub when the prompt "For which GitHub repository would you like to set up a GitHub workflow?" appears.

  • When you see the prompt "Set up the workflow to run a build script before every deploy?" enter y

  • Enter the following command for the prompt "What script should be run before every deploy?":

    npm install && npm run build:firebase
  • When you see the prompt "Set up automatic deployment to your site's live channel when a PR is merged?" enter y

  • Enter "main" for the prompt "What is the name of the GitHub branch associated with your site's live channel?"

There should be two new .yml files, firebase-hosting-pull-request.yml and firebase-hosting-merge.yml, created in the .github/workflows directory for a deployment preview for each pull request and the official deployment when merged onto the main branch. Double check that the correct run script is present in both files.

Firebase actions

- - +
Version: 3.0.0

Automated Builds

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD?

CI/CD refers to Continuous Integration and either Continuous Delivery or Continuous Deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

GitHub Actions are written as YML files inside a .github/worflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows. Mac and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds PsiTurk version when linux or all operating systems are selected
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage on private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their [official documentation](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions).

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file, install and run.

The executable does not require installation of any additional software.

Uninstall the task

Windows

Go to System Settings: Add or remove programs. Look for the name of your task in the installed programs list, and Uninstall.

The executable does not require installation of any additional software.

Firebase Hosting

Automatic deployment on a firebase hosting site can also be setup with github actions. Before proceeding with the following steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase. Then run the following command in the terminal:

firebase init hosting:github
  • Be sure to type "<username>/<repository name>" exactly as it appears in GitHub when the prompt "For which GitHub repository would you like to set up a GitHub workflow?" appears.

  • When you see the prompt "Set up the workflow to run a build script before every deploy?" enter y

  • Enter the following command for the prompt "What script should be run before every deploy?":

    npm install && npm run build:firebase
  • When you see the prompt "Set up automatic deployment to your site's live channel when a PR is merged?" enter y

  • Enter "main" for the prompt "What is the name of the GitHub branch associated with your site's live channel?"

There should be two new .yml files, firebase-hosting-pull-request.yml and firebase-hosting-merge.yml, created in the .github/workflows directory for a deployment preview for each pull request and the official deployment when merged onto the main branch. Double check that the correct run script is present in both files.

Firebase actions

+ + \ No newline at end of file diff --git a/docs/3.0.0/configuration/index.html b/docs/3.0.0/configuration/index.html index 9a7a6078..c324c6b7 100644 --- a/docs/3.0.0/configuration/index.html +++ b/docs/3.0.0/configuration/index.html @@ -3,14 +3,14 @@ -Configuration | Honeycomb - - +Configuration | Honeycomb + +
-
Version: 3.0.0

Configuration

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text. Optional variables are labeled with the optional badge and mandatory variables are labeled with the default <default-value> badge with their default value specified. The buildtime badge indicates the variable is used during the build/compilation phase (npm build) while the runtime badge indicates the variable is used during the executable run (npm run dev).

Dev Mode Only

  • ELECTRON_START_URL stringoptional: URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode.

Desktop Only

  • EVENT_MARKER_PRODUCT_IDstringoptionalruntime: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME stringoptionalruntime: The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_VIDEObooleandefault falsebuildtime: whether the participant is being video recorded. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_EEGbooleandefault falsebuildtime: whether the event marker/EEG is available. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_PHOTODIODEbooleandefault falsebuildtime: whether the photodiode is in use. This can be used when the task is running as a desktop app (electron).

Desktop and Online

  • REACT_APP_VOLUMEbooleandefault falsebuildtime: whether the participant is being asked to adjust volume. This can be used on both the desktop (electron) and online settings.
  • REACT_APP_PARTICIPANT_ID stringoptionalruntime: The default participant id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.
  • REACT_APP_STUDY_ID stringoptionalruntime: The default study id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.

Understanding Build Time and Run Time Variables

  • runtime: Run-time environment variables allow for quick changes before running the task. They are convenient since they don't require building a whole different executable. For a Desktop Application, these are set at the system level and must be available at the time where the task runs. See this tutorial for OS specific instructions.. For a Firebase Application, these must be stored in the Firestore.

  • build time: Build-time environment variable are configured before the application is built and cannot be changed at run-time. They are configured via .env files before building. Instead of using a single .env file, we prefer to defined separate files under the env/ directory, and use a package called dotenv-cli before building`.

The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. This command does not run directly from the command line (terminal). Instead, to set build-time environment variables, we need to add a script to package.json with the following format:

"[build|dev]:<script name>": "dotenv -e env/<your env file> npm run [build|dev]"

Honeycomb includes so scripts for common scenarios. For instance, you can run:

npm run dev:home
npm run dev:home:video
npm run dev:clinic
npm run dev:clinic:video
npm run dev:firebase
- - +
Version: 3.0.0

Configuration

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text. Optional variables are labeled with the optional badge and mandatory variables are labeled with the default <default-value> badge with their default value specified. The buildtime badge indicates the variable is used during the build/compilation phase (npm build) while the runtime badge indicates the variable is used during the executable run (npm run dev).

Dev Mode Only

  • ELECTRON_START_URL stringoptional: URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode.

Desktop Only

  • EVENT_MARKER_PRODUCT_IDstringoptionalruntime: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME stringoptionalruntime: The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_VIDEObooleandefault falsebuildtime: whether the participant is being video recorded. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_EEGbooleandefault falsebuildtime: whether the event marker/EEG is available. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_PHOTODIODEbooleandefault falsebuildtime: whether the photodiode is in use. This can be used when the task is running as a desktop app (electron).

Desktop and Online

  • REACT_APP_VOLUMEbooleandefault falsebuildtime: whether the participant is being asked to adjust volume. This can be used on both the desktop (electron) and online settings.
  • REACT_APP_PARTICIPANT_ID stringoptionalruntime: The default participant id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.
  • REACT_APP_STUDY_ID stringoptionalruntime: The default study id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.

Understanding Build Time and Run Time Variables

  • runtime: Run-time environment variables allow for quick changes before running the task. They are convenient since they don't require building a whole different executable. For a Desktop Application, these are set at the system level and must be available at the time where the task runs. See this tutorial for OS specific instructions.. For a Firebase Application, these must be stored in the Firestore.

  • build time: Build-time environment variable are configured before the application is built and cannot be changed at run-time. They are configured via .env files before building. Instead of using a single .env file, we prefer to defined separate files under the env/ directory, and use a package called dotenv-cli before building`.

The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. This command does not run directly from the command line (terminal). Instead, to set build-time environment variables, we need to add a script to package.json with the following format:

"[build|dev]:<script name>": "dotenv -e env/<your env file> npm run [build|dev]"

Honeycomb includes so scripts for common scenarios. For instance, you can run:

npm run dev:home
npm run dev:home:video
npm run dev:clinic
npm run dev:clinic:video
npm run dev:firebase
+ + \ No newline at end of file diff --git a/docs/3.0.0/event_triggers/index.html b/docs/3.0.0/event_triggers/index.html index 9b5a7bb1..d2b06d4c 100644 --- a/docs/3.0.0/event_triggers/index.html +++ b/docs/3.0.0/event_triggers/index.html @@ -3,14 +3,14 @@ -Set up event triggers | Honeycomb - - +Set up event triggers | Honeycomb + +
-
Version: 3.0.0

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set to the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here.

Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

Send event code triggers

Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncodewith the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

- - +
Version: 3.0.0

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set to the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here.

Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

Send event code triggers

Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncodewith the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

+ + \ No newline at end of file diff --git a/docs/3.0.0/firebase/index.html b/docs/3.0.0/firebase/index.html index 70ac7d42..90ff8217 100644 --- a/docs/3.0.0/firebase/index.html +++ b/docs/3.0.0/firebase/index.html @@ -3,14 +3,14 @@ -Set up Firebase | Honeycomb - - +Set up Firebase | Honeycomb + +
-
Version: 3.0.0

Set up Firebase

Honeycomb comes with methods and configurations for easy Firebase and Cloud Firestore set up. Please use this section to configure Firebase Hosting services and Firestore cloud storage.

Setting up Firebase

0. Installing the Firebase Command Line Interface

To check if firebase has been installed, type firebase into a terminal window.

firebase

If a list of options are printed on the terminal then the firebase tool has already been installed. If not, you will get an error - something along the lines of "Command not found." The firebase-cli can then be installed using npm:

npm install -g firebase-tools

The -g flag installs an npm package globally on your system, as opposed to the current project

1. Initializing Firebase account and project

  • Create and login to a Firebase account on the Firebase website.

  • Create a Firebase project by clicking add project and enter a Project Name.

2. Linking firebase to task

  • Login to Firebase using firebase login command in the terminal.

  • Navigate to the .firebaserc file home directory and edit the "default" field with the project name given in part 1.

{
"projects": {
"default": "<your project name>"
}
}

3. Copying web app credentials

  • Navigate to the firebase console and select the project.
  • Create a new Web App by clicking on Add App or the </> code symbol and following the prompts.
  • Enter the a name for the Firebase app (could be the same as your Honeycomb task repo name).
  • Check "Also set up Firebase Hosting for this app."
  • Click Register App. This should auto-generate a script with several values that you need to copy into the next step.
  • Copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo:
REACT_APP_FIREBASE="true"
REACT_APP_apiKey=
REACT_APP_authDomain=
REACT_APP_projectId=
REACT_APP_storageBucket=
REACT_APP_messagingSenderId=
REACT_APP_appId=
  • Copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase you just created.
    • You only need to copy the variables referenced here. If you enabled Google Analytics during project creation, additional variables may be printed in the console. You don't need to copy those.

Firebase is now set up!

Setting up Firestore

Honeycomb includes cloud storage for task data using Firestore. Follow these steps to initialize Firestore:

  • Navigate to the current project in the developer console and select Firestore Database from the sidebar.
  • Click Create Database, select production mode and choose the current location for the cloud storage bucket.

Firestore security rules

Firestore Security Rules provides easy server-side authorization to the database. For a honeycomb task, we use the security rules to allow access to only authorized participants for a specified study. Honeycomb's default set of rules is included in the firestore.rules file in the home directory. This file can be edited to change the rules. To deploy the rules in the file, type the following line of code in the terminal:

firebase deploy --only firestore:rules

Alternatively, Editing the rules directly in the console is also possible. To do so, navigate to the Rules tab in the Firestore Database section from the firebase console sidebar then copy and paste the code that is in the firestore.rules file.

Firestore database and rules are now both deployed. For Honeycomb's default set of rules, to add an authorized participant for a study, create a collection named registered_studies, add a study with the study ID as the document name in that collection. For each registered study, add an array field named registered_participants where each element in the array will be an authorized participant for that study.

Example Task

- - +
Version: 3.0.0

Set up Firebase

Honeycomb comes with methods and configurations for easy Firebase and Cloud Firestore set up. Please use this section to configure Firebase Hosting services and Firestore cloud storage.

Setting up Firebase

0. Installing the Firebase Command Line Interface

To check if firebase has been installed, type firebase into a terminal window.

firebase

If a list of options are printed on the terminal then the firebase tool has already been installed. If not, you will get an error - something along the lines of "Command not found." The firebase-cli can then be installed using npm:

npm install -g firebase-tools

The -g flag installs an npm package globally on your system, as opposed to the current project

1. Initializing Firebase account and project

  • Create and login to a Firebase account on the Firebase website.

  • Create a Firebase project by clicking add project and enter a Project Name.

2. Linking firebase to task

  • Login to Firebase using firebase login command in the terminal.

  • Navigate to the .firebaserc file home directory and edit the "default" field with the project name given in part 1.

{
"projects": {
"default": "<your project name>"
}
}

3. Copying web app credentials

  • Navigate to the firebase console and select the project.
  • Create a new Web App by clicking on Add App or the </> code symbol and following the prompts.
  • Enter the a name for the Firebase app (could be the same as your Honeycomb task repo name).
  • Check "Also set up Firebase Hosting for this app."
  • Click Register App. This should auto-generate a script with several values that you need to copy into the next step.
  • Copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo:
REACT_APP_FIREBASE="true"
REACT_APP_apiKey=
REACT_APP_authDomain=
REACT_APP_projectId=
REACT_APP_storageBucket=
REACT_APP_messagingSenderId=
REACT_APP_appId=
  • Copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase you just created.
    • You only need to copy the variables referenced here. If you enabled Google Analytics during project creation, additional variables may be printed in the console. You don't need to copy those.

Firebase is now set up!

Setting up Firestore

Honeycomb includes cloud storage for task data using Firestore. Follow these steps to initialize Firestore:

  • Navigate to the current project in the developer console and select Firestore Database from the sidebar.
  • Click Create Database, select production mode and choose the current location for the cloud storage bucket.

Firestore security rules

Firestore Security Rules provides easy server-side authorization to the database. For a honeycomb task, we use the security rules to allow access to only authorized participants for a specified study. Honeycomb's default set of rules is included in the firestore.rules file in the home directory. This file can be edited to change the rules. To deploy the rules in the file, type the following line of code in the terminal:

firebase deploy --only firestore:rules

Alternatively, Editing the rules directly in the console is also possible. To do so, navigate to the Rules tab in the Firestore Database section from the firebase console sidebar then copy and paste the code that is in the firestore.rules file.

Firestore database and rules are now both deployed. For Honeycomb's default set of rules, to add an authorized participant for a study, create a collection named registered_studies, add a study with the study ID as the document name in that collection. For each registered study, add an array field named registered_participants where each element in the array will be an authorized participant for that study.

Example Task

+ + \ No newline at end of file diff --git a/docs/3.0.0/folders/index.html b/docs/3.0.0/folders/index.html index 4b212964..c0de403d 100644 --- a/docs/3.0.0/folders/index.html +++ b/docs/3.0.0/folders/index.html @@ -3,14 +3,14 @@ -Project Organization | Honeycomb - - +Project Organization | Honeycomb + +
-
Version: 3.0.0

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used (and definitely not mutated), and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code. Below are descriptions of the main files and folders.

package.json

The package.json file contains metadata about your project and scripts to run tasks related to your task. The name should be updated to your task's name and scripts can be added as desired, but otherwise this file should not be edited manually. To remove or add a dependency use npm install or npm uninstall with the -D flag if installing a dev dependency.

The package-lock.json contains metadata about the package installation. It should never be manually updated.

assets/

This folder contains any static files that are used by the app, such as the images used as icons for the installed applications.

env/

This folder contains different .env files with presets for common use cases. These files can be loaded with dotenv, which is explained in greater detail in the Configuration section.

.github/workflows/

This folder contains different .yaml files which are used to configure the build tests (build.yaml) following a push and to create task executables either in a single instance (package.yaml) or for a full release (release.yaml).

public/

The public directory contains files that are used as assets in the built app. The favicon.ico is the small icon you can see in the browser tab (on Chrome) - it is set to Brown's logo in the project. The index.html contains the shell of your website - the name displayed on the tab can be changed here, otherwise it shouldn't need to be edited. The scripts included in the file are for psiturk as are the files in the lib/ directory.

electron.js

This file contains all of the code relating to the Electron app. This includes the event-marker, throwing errors via dialog windows, saving data, and reading files.

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes.

In the config/ directory, there are .js files which contain settings for the different parts of the task. Every task should have a main config and a trigger config (assuming use of the event marker). The main config has all global settings for the task (such as whether it is in mturk mode or not), load the appropriate language file, and set up a default (or only) configuration object for the task. Different in-task features can be loaded from .env files and is set in the main config. For example, we have included some of these files in the env directory (e.g. env.clinic file enables event marker, photodiode and volume adjustment). The trigger config has settings specific to the event marker and uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment. Also, note that the productId can be overwritten by the environment variable EVENT_MARKER_PRODUCT_ID.

src/

This folder contains the code for the app, the vast majority of changes and code should go here.

App.jsx

This is the starting point for the app. The <Login> component handles user authentication in the different use cases and the <JsPsychExperiment> component initializes the jspsych 7 experiment. This is also where communication is set up with the electron and psiturk processes.

App.css

This is where styling for the app is housed. If colors, fonts, spacing, etc. need to be set, do it here.

components/

This folder contains the components referenced in App.jsx. This includes the Honeycomb <JsPsychExperiment> component which connects the Honyecomb login page to your jspsych 7 experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. English and Spanish) as well as allows for mturk-specific language. This also makes it easy to re-use common phrases in many places in the task.

lib/

The lib/ directory contains utility functions and markup that is used in the tasks. This allows for functions and html to be re-used wherever needed. The lib/utils.js file contains functions that are generally useful across many tasks, whereas lib/taskUtils.js contains functions specific to this task.

lib/markup

markup files should contain primarily templates for HTML that are used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

timelines

jspsych uses timelines to control what trials are displayed in what order. timelines can contain other timelines, which is why there may be several files in this directory. The main.js file should have the timeline that is called by App.jsx in the <JsPsychExperiment> component.

trials

jspsych uses trials as its base unit of an experiment. These trials do things such as display some stimulus or request a response.

- - +
Version: 3.0.0

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used (and definitely not mutated), and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code. Below are descriptions of the main files and folders.

package.json

The package.json file contains metadata about your project and scripts to run tasks related to your task. The name should be updated to your task's name and scripts can be added as desired, but otherwise this file should not be edited manually. To remove or add a dependency use npm install or npm uninstall with the -D flag if installing a dev dependency.

The package-lock.json contains metadata about the package installation. It should never be manually updated.

assets/

This folder contains any static files that are used by the app, such as the images used as icons for the installed applications.

env/

This folder contains different .env files with presets for common use cases. These files can be loaded with dotenv, which is explained in greater detail in the Configuration section.

.github/workflows/

This folder contains different .yaml files which are used to configure the build tests (build.yaml) following a push and to create task executables either in a single instance (package.yaml) or for a full release (release.yaml).

public/

The public directory contains files that are used as assets in the built app. The favicon.ico is the small icon you can see in the browser tab (on Chrome) - it is set to Brown's logo in the project. The index.html contains the shell of your website - the name displayed on the tab can be changed here, otherwise it shouldn't need to be edited. The scripts included in the file are for psiturk as are the files in the lib/ directory.

electron.js

This file contains all of the code relating to the Electron app. This includes the event-marker, throwing errors via dialog windows, saving data, and reading files.

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes.

In the config/ directory, there are .js files which contain settings for the different parts of the task. Every task should have a main config and a trigger config (assuming use of the event marker). The main config has all global settings for the task (such as whether it is in mturk mode or not), load the appropriate language file, and set up a default (or only) configuration object for the task. Different in-task features can be loaded from .env files and is set in the main config. For example, we have included some of these files in the env directory (e.g. env.clinic file enables event marker, photodiode and volume adjustment). The trigger config has settings specific to the event marker and uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment. Also, note that the productId can be overwritten by the environment variable EVENT_MARKER_PRODUCT_ID.

src/

This folder contains the code for the app, the vast majority of changes and code should go here.

App.jsx

This is the starting point for the app. The <Login> component handles user authentication in the different use cases and the <JsPsychExperiment> component initializes the jspsych 7 experiment. This is also where communication is set up with the electron and psiturk processes.

App.css

This is where styling for the app is housed. If colors, fonts, spacing, etc. need to be set, do it here.

components/

This folder contains the components referenced in App.jsx. This includes the Honeycomb <JsPsychExperiment> component which connects the Honyecomb login page to your jspsych 7 experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. English and Spanish) as well as allows for mturk-specific language. This also makes it easy to re-use common phrases in many places in the task.

lib/

The lib/ directory contains utility functions and markup that is used in the tasks. This allows for functions and html to be re-used wherever needed. The lib/utils.js file contains functions that are generally useful across many tasks, whereas lib/taskUtils.js contains functions specific to this task.

lib/markup

markup files should contain primarily templates for HTML that are used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

timelines

jspsych uses timelines to control what trials are displayed in what order. timelines can contain other timelines, which is why there may be several files in this directory. The main.js file should have the timeline that is called by App.jsx in the <JsPsychExperiment> component.

trials

jspsych uses trials as its base unit of an experiment. These trials do things such as display some stimulus or request a response.

+ + \ No newline at end of file diff --git a/docs/3.0.0/index.html b/docs/3.0.0/index.html index 0ca190e6..76f4916f 100644 --- a/docs/3.0.0/index.html +++ b/docs/3.0.0/index.html @@ -3,14 +3,14 @@ -Introduction | Honeycomb - - +Introduction | Honeycomb + +
-
Version: 3.0.0

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy to install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych 7 tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

Community Driven

Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

Cite this work

If you use Honeycomb in your work, please cite

Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

- - +
Version: 3.0.0

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy to install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych 7 tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

Community Driven

Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

Cite this work

If you use Honeycomb in your work, please cite

Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

+ + \ No newline at end of file diff --git a/docs/3.0.0/npm_scripts/index.html b/docs/3.0.0/npm_scripts/index.html index c3793bc9..f53780b9 100644 --- a/docs/3.0.0/npm_scripts/index.html +++ b/docs/3.0.0/npm_scripts/index.html @@ -3,14 +3,14 @@ -NPM Scripts | Honeycomb - - +NPM Scripts | Honeycomb + +
-
Version: 3.0.0

NPM Scripts

In the project directory, you can run:

npm run dev

Runs npm start and npm run electron-dev concurrently. This may not play nicely with windows. If it doesn't, run npm start and npm run electron-dev from different terminal windows.

npm start

Runs the app in the development mode.

Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.

See the section about running tests for more information.

npm build

Creates a production build of the app (renderer). This must be done before running package:platform or the psiturk build instructions.

npm run package:platform

Uses Electron to build the app and create a standalone installer for the given platform. Supported platforms are:

  • npm run package:windows
  • npm run package:linux
  • npm run package:mac

The output can be found in the ./out subfolder.

Note: Packaging for windows on a non-windows machine requires mono and wine to be installed.

npm run eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Run Electron

npm run electron

Run the built app.

npm run electron-dev

Run the current state of the code (un-built).

- - +
Version: 3.0.0

NPM Scripts

In the project directory, you can run:

npm run dev

Runs npm start and npm run electron-dev concurrently. This may not play nicely with windows. If it doesn't, run npm start and npm run electron-dev from different terminal windows.

npm start

Runs the app in the development mode.

Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.

You will also see any lint errors in the console.

npm test

Launches the test runner in the interactive watch mode.

See the section about running tests for more information.

npm build

Creates a production build of the app (renderer). This must be done before running package:platform or the psiturk build instructions.

npm run package:platform

Uses Electron to build the app and create a standalone installer for the given platform. Supported platforms are:

  • npm run package:windows
  • npm run package:linux
  • npm run package:mac

The output can be found in the ./out subfolder.

Note: Packaging for windows on a non-windows machine requires mono and wine to be installed.

npm run eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Run Electron

npm run electron

Run the built app.

npm run electron-dev

Run the current state of the code (un-built).

+ + \ No newline at end of file diff --git a/docs/3.0.0/online_integration/index.html b/docs/3.0.0/online_integration/index.html index 536991c4..9bcd3f4f 100644 --- a/docs/3.0.0/online_integration/index.html +++ b/docs/3.0.0/online_integration/index.html @@ -3,18 +3,18 @@ -Deploy online | Honeycomb - - +Deploy online | Honeycomb + +
-
Version: 3.0.0

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a psiturk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. +

Version: 3.0.0

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a psiturk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

  • Build the application: npm run build

  • Move to the psiturkit directory: cd psiturkit

  • If it's the first time you're running the script:
    ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>

  • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):
    ./psiturk-it -u -p <PATH_TO_NEW_PSITURK_PROJECT>

Running psiturk

After that, just navigate to your newly created PsiTurk project directory.

shell> psiturk #start psiturk
psiturk> server on #start server
psiturk> debug #debug mode

Running on the Web

Using Github Pages

Running npm run build generates static content into the build directory that can be served using any static contents hosting service. The workflow .github/workflows/release-home-all.yml uploads the build directory to the gh-branch to serve the application on GitHub pages as an example. After a creating a tag, the workflow will run and your application will be served at <githubuser>.github.io/<repository>. -For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.
  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.
  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.
  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.
  5. To create the secret copy your private key e.g. xclip -sel clip < ~/.ssh/id_rsa and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.
  6. Make sure the publishing source for your repository is configured for gh-pages branch.

Using Firebase

We have included methods and configurations for close integration with firebase. Before proceeding with the follwing steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase.

  1. Run npm run build:firebase in the terminal to create a production build for firebase.
  2. Run firebase deploy in the terminal to deploy the production build.
  3. The production build is now deployed to the firebase project domain.

To automate firebase deployments, we have included instructions on setting up firebase github actions on our Automated Builds page

- - +For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.
  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.
  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.
  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.
  5. To create the secret copy your private key e.g. xclip -sel clip < ~/.ssh/id_rsa and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.
  6. Make sure the publishing source for your repository is configured for gh-pages branch.

Using Firebase

We have included methods and configurations for close integration with firebase. Before proceeding with the follwing steps, please make sure that firebase is configured by following the Getting started with firebase section under Set Up Firebase.

  1. Run npm run build:firebase in the terminal to create a production build for firebase.
  2. Run firebase deploy in the terminal to deploy the production build.
  3. The production build is now deployed to the firebase project domain.

To automate firebase deployments, we have included instructions on setting up firebase github actions on our Automated Builds page

+ + \ No newline at end of file diff --git a/docs/3.0.0/quick_start/index.html b/docs/3.0.0/quick_start/index.html index 3808d8a5..cd56a80c 100644 --- a/docs/3.0.0/quick_start/index.html +++ b/docs/3.0.0/quick_start/index.html @@ -3,14 +3,14 @@ -Quick Start | Honeycomb - - +Quick Start | Honeycomb + +
-
Version: 3.0.0

Quick Start

Before we can get started with Honeycomb, we must make sure our machines have the required prerequisites for Honeycomb to run.

1. Install a Package Manager

There are some prerequisites that are required across all operating systems to run Honeycomb. We will be using a package manager to install these dependencies.

MacOS Package Manager (Homebrew)

Paste the following in a macOS Terminal and press enter to install Homebrew, then follow the steps in the terminal screen.

/bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'

When this command is run, additional installations may be automatically added by Homebrew based on your machine's configurations. Homebrew will prompt you to Press RETURN to continue or any other key to abort. Please continue with these installations by pressing Return

Set up Homebrew on your PATH

To make Homebrew available in your shell, we need to add the Homebrew installation location to our PATH. This should be done automatically on macOS 10.14 Mojave or newer. For older versions, or to do it manually run the following command in your terminal.

echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile

If you're using zsh, also add to your ~/.zshrc file.

Windows Package Manager (Chocolatey)

Chocolatey is a package manager for Windows - essentially the equivalent of Homebrew for MacOs. It installs software from the command line and makes updates much easier. Run Powershell with administrator privileges and paste the following command:

Run Powershell as an admin form the start menu

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

2. Start your new task from our template repository

To start a new task locally, in development mode follow these steps:

The simplest way to get started is creating a new repository using Honeycomb as a template. This option will allow you to generate a new repository with the same directory structure and files as an existing repository.

Creating a repository from a template is similar to forking a repository, but there are important differences:

  • A new fork includes the entire commit history of the parent repository, while a repository created from a template starts with a single commit.
  • Commits to a fork don't appear in your contributions graph, while commits to a repository created from a template do appear in your contribution graph.
  • A fork can be a temporary way to contribute code to an existing project, while creating a repository from a template starts a new project quickly.

Go to https://github.com/brown-ccv/honeycomb and click on Use this template on the top right.

Use this template

Then select the organization and the name of your repository and click on create repository from template.

Create repository

Alternatively, you can use GitHub CLI to create a new project based on the Honeycomb template repository. First, install GitHub CLI (https://cli.github.com/), then run on your terminal:

gh repo create your-new-task-name --template brown-ccv/honeycomb

You can now move into the directory that was just created

cd your-new-task-name

3. Install Prerequisites

Running Brewfile (macOS)

A Brewfile is a script that developers can use to install multiple software tools that are required to run an application.

brew bundle

This will call the brew command which will install all the listed packages to your project.

Using Chocolatey (Windows)

Chocolatey will install multiple software packages if given a configuration file. The honeycomb template repository includes one! See Setup Details for more information about using chocolatey.

choco install chocolatey.config
Python on Windows

In addition to the packages installed by Chocolatey you need to complete your Python installation using pyenv. Please complete the steps in Python on Windows before continuing.

4. Change name and description

It's best practice to create a new branch whenever we look to make changes and/or add a new feature. Your IDE may have a way to do this or it can always be done on the command line.

git checkout -b <branch-name>

Open package.json and edit it to reflect your app name and description (e.g. name, author, repository). Save your changes and commit them to git:

git commit -m "Commit message goes here!"

Checkout the Version Control page for more information about working with git

5. Install NPM Packages

npm is a command-line utility for Node.js that makes it easy for you to install packages and maintain them throughout the lifecycle of your application. With Node.js installed in Step 0, we are now able to utilize the npm command in the terminal.

Please run the following command to trigger the installation of all the dependencies relevant to this project:

npm install

Honeycomb, like most applications, contains a template called package.json. This file contains three distinctive parts that we interact with using a series of npm commands.

Metadata

{
"name": "honeycomb",
"description": "all-in-one task starter app with jsPsych + React + Electron + psiturk ",
"author": {
"name": "Brown CCV",
"email": "ccv-bot@brown.edu",
"url": "ccv.brown.edu"
}
}

The metadata provides information about the project such as the name, author and description.

Dependencies

"dependencies": {
"@brown-ccv/behavioral-task-trials": "^2.0.0",
"@fortawesome/fontawesome-free": "^5.9.0",
"bootstrap": "^5.2.0-beta1",
"electron-log": "^4.4.8",
"electron-squirrel-startup": "^1.0.0",
"event-marker": "git+https://github.com/brown-ccv/event-marker.git",
...
}

Dependencies are packages that the project rely on for it to function properly.

They are formatted in specific key/value pairs where every key is a name of the package and the value is the version range that’s acceptable.

Note: If any changes are made to the dependencies section of the package.json, you must run npm install again to download the newly updated list of dependencies.

Scripts

"scripts": {
"commit": "git-cz",
"postinstall": "node version.js && npm run rebuild",
"start": "cross-env BROWSER=\"none\" NODE_PATH=\"./src\" react-scripts start",
"start:browser": "react-scripts start",
"test": "react-scripts test",
"prebuild": "electron-rebuild",
"build": "react-scripts build",
...
}

The scripts section contains a number of commands you can run.

Check out the NPM Scripts page for more information about the different scripts you can run.

6. Run the task in dev mode

npm run dev

This will launch an electron window with the task and inspector open. It will hot-reload whenever changes are made to the app.

Scripts on Windows

Windows users must use a Git Bash terminal to execute scripts such as npm run dev. This is because node scripts are designed to execute on a Unix style command line environment but neither Command Prompt nor PowerShell are Unix based.

Check out these instructions to set git bash as your default terminal on VS Code.

7. Learn about configuring your task for different environments

HoneyComb tasks can be configured to run as a web app in Firebase, as desktop application via electron, to receive port signals from EEG, cameras, foot pedals and more. To learn more about how to configure your task for these different scenarios, see the Configuration Section.

8. Check out the data

The data is saved throughout the task. When running as a Desktop App, data is saved to the user's app directory. When running as Web App in Firebase, data is stored in the FireStore.

For a Desktop App, the location of the is logged at the beginning of the task wherever you ran npm run dev. Data is also stored in a folder that is generated by the app, which should be found on the desktop.

9. Quit the task

If you want to quit in the middle of the task, you can use these keyboard shortcuts:

Ctrl+W (for PC/Windows)
Cmd+Q (for Mac)

Partial data will be saved.

10. Run automated tests

Automated tests can tell a user whether the code is working as expected or if recent changes have broken previous functionality. Running automated tests is a good idea whenever you're getting started, merging updates, or making custom changes.

To run the tests interactively:

npm test

Or non-interactively:

CI=true npm test

Testing on Linux

When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runner creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

This is a "known issue" with some test runners on Linux, as in discussions here and here.

One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

  • Command that initially fails with ENOSPC: npm test
  • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
  • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
  • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
  • Save, exit, and reload the config file: sudo sysctl -p
  • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
  • Retry the initial command, which should now succeed: npm test
- - +
Version: 3.0.0

Quick Start

Before we can get started with Honeycomb, we must make sure our machines have the required prerequisites for Honeycomb to run.

1. Install a Package Manager

There are some prerequisites that are required across all operating systems to run Honeycomb. We will be using a package manager to install these dependencies.

MacOS Package Manager (Homebrew)

Paste the following in a macOS Terminal and press enter to install Homebrew, then follow the steps in the terminal screen.

/bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'

When this command is run, additional installations may be automatically added by Homebrew based on your machine's configurations. Homebrew will prompt you to Press RETURN to continue or any other key to abort. Please continue with these installations by pressing Return

Set up Homebrew on your PATH

To make Homebrew available in your shell, we need to add the Homebrew installation location to our PATH. This should be done automatically on macOS 10.14 Mojave or newer. For older versions, or to do it manually run the following command in your terminal.

echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile

If you're using zsh, also add to your ~/.zshrc file.

Windows Package Manager (Chocolatey)

Chocolatey is a package manager for Windows - essentially the equivalent of Homebrew for MacOs. It installs software from the command line and makes updates much easier. Run Powershell with administrator privileges and paste the following command:

Run Powershell as an admin form the start menu

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

2. Start your new task from our template repository

To start a new task locally, in development mode follow these steps:

The simplest way to get started is creating a new repository using Honeycomb as a template. This option will allow you to generate a new repository with the same directory structure and files as an existing repository.

Creating a repository from a template is similar to forking a repository, but there are important differences:

  • A new fork includes the entire commit history of the parent repository, while a repository created from a template starts with a single commit.
  • Commits to a fork don't appear in your contributions graph, while commits to a repository created from a template do appear in your contribution graph.
  • A fork can be a temporary way to contribute code to an existing project, while creating a repository from a template starts a new project quickly.

Go to https://github.com/brown-ccv/honeycomb and click on Use this template on the top right.

Use this template

Then select the organization and the name of your repository and click on create repository from template.

Create repository

Alternatively, you can use GitHub CLI to create a new project based on the Honeycomb template repository. First, install GitHub CLI (https://cli.github.com/), then run on your terminal:

gh repo create your-new-task-name --template brown-ccv/honeycomb

You can now move into the directory that was just created

cd your-new-task-name

3. Install Prerequisites

Running Brewfile (macOS)

A Brewfile is a script that developers can use to install multiple software tools that are required to run an application.

brew bundle

This will call the brew command which will install all the listed packages to your project.

Using Chocolatey (Windows)

Chocolatey will install multiple software packages if given a configuration file. The honeycomb template repository includes one! See Setup Details for more information about using chocolatey.

choco install chocolatey.config
Python on Windows

In addition to the packages installed by Chocolatey you need to complete your Python installation using pyenv. Please complete the steps in Python on Windows before continuing.

4. Change name and description

It's best practice to create a new branch whenever we look to make changes and/or add a new feature. Your IDE may have a way to do this or it can always be done on the command line.

git checkout -b <branch-name>

Open package.json and edit it to reflect your app name and description (e.g. name, author, repository). Save your changes and commit them to git:

git commit -m "Commit message goes here!"

Checkout the Version Control page for more information about working with git

5. Install NPM Packages

npm is a command-line utility for Node.js that makes it easy for you to install packages and maintain them throughout the lifecycle of your application. With Node.js installed in Step 0, we are now able to utilize the npm command in the terminal.

Please run the following command to trigger the installation of all the dependencies relevant to this project:

npm install

Honeycomb, like most applications, contains a template called package.json. This file contains three distinctive parts that we interact with using a series of npm commands.

Metadata

{
"name": "honeycomb",
"description": "all-in-one task starter app with jsPsych + React + Electron + psiturk ",
"author": {
"name": "Brown CCV",
"email": "ccv-bot@brown.edu",
"url": "ccv.brown.edu"
}
}

The metadata provides information about the project such as the name, author and description.

Dependencies

"dependencies": {
"@brown-ccv/behavioral-task-trials": "^2.0.0",
"@fortawesome/fontawesome-free": "^5.9.0",
"bootstrap": "^5.2.0-beta1",
"electron-log": "^4.4.8",
"electron-squirrel-startup": "^1.0.0",
"event-marker": "git+https://github.com/brown-ccv/event-marker.git",
...
}

Dependencies are packages that the project rely on for it to function properly.

They are formatted in specific key/value pairs where every key is a name of the package and the value is the version range that’s acceptable.

Note: If any changes are made to the dependencies section of the package.json, you must run npm install again to download the newly updated list of dependencies.

Scripts

"scripts": {
"commit": "git-cz",
"postinstall": "node version.js && npm run rebuild",
"start": "cross-env BROWSER=\"none\" NODE_PATH=\"./src\" react-scripts start",
"start:browser": "react-scripts start",
"test": "react-scripts test",
"prebuild": "electron-rebuild",
"build": "react-scripts build",
...
}

The scripts section contains a number of commands you can run.

Check out the NPM Scripts page for more information about the different scripts you can run.

6. Run the task in dev mode

npm run dev

This will launch an electron window with the task and inspector open. It will hot-reload whenever changes are made to the app.

Scripts on Windows

Windows users must use a Git Bash terminal to execute scripts such as npm run dev. This is because node scripts are designed to execute on a Unix style command line environment but neither Command Prompt nor PowerShell are Unix based.

Check out these instructions to set git bash as your default terminal on VS Code.

7. Learn about configuring your task for different environments

HoneyComb tasks can be configured to run as a web app in Firebase, as desktop application via electron, to receive port signals from EEG, cameras, foot pedals and more. To learn more about how to configure your task for these different scenarios, see the Configuration Section.

8. Check out the data

The data is saved throughout the task. When running as a Desktop App, data is saved to the user's app directory. When running as Web App in Firebase, data is stored in the FireStore.

For a Desktop App, the location of the is logged at the beginning of the task wherever you ran npm run dev. Data is also stored in a folder that is generated by the app, which should be found on the desktop.

9. Quit the task

If you want to quit in the middle of the task, you can use these keyboard shortcuts:

Ctrl+W (for PC/Windows)
Cmd+Q (for Mac)

Partial data will be saved.

10. Run automated tests

Automated tests can tell a user whether the code is working as expected or if recent changes have broken previous functionality. Running automated tests is a good idea whenever you're getting started, merging updates, or making custom changes.

To run the tests interactively:

npm test

Or non-interactively:

CI=true npm test

Testing on Linux

When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runner creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

This is a "known issue" with some test runners on Linux, as in discussions here and here.

One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

  • Command that initially fails with ENOSPC: npm test
  • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
  • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
  • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
  • Save, exit, and reload the config file: sudo sysctl -p
  • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
  • Retry the initial command, which should now succeed: npm test
+ + \ No newline at end of file diff --git a/docs/3.0.0/setup_details/index.html b/docs/3.0.0/setup_details/index.html index 3ae41f00..aef3d43e 100644 --- a/docs/3.0.0/setup_details/index.html +++ b/docs/3.0.0/setup_details/index.html @@ -3,15 +3,15 @@ -Setup Details | Honeycomb - - +Setup Details | Honeycomb + +
-
Version: 3.0.0

Setup Details

Prerequisites

It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. First we need the following programs

  • git (version control and GitHub integration)
  • nodejs (web development - we recommend the latest long term support version)
  • python (3.7 or later)
  • An Integrated Development Environment (we recommend VS Code)

In addition, Honeycomb relies on Electron to package the cross-platform desktop applications. Some of electron's prerequisites are platform dependant - listed below are the prerequisites for each operating system along with resources for manually installing them.

MacOS

Brew

All of the required dependencies for honeycomb on MacOS can be installed via the brewfile. See the quick start for more information.

Manual Installation (MacOS)

Windows

Note that Windows occasionally requires a restart after package installations complete. If you are running into issues after installing the packages please restart your terminal and/or your entire computer. This should resolve most issues.

chocolatey

chocolatey.config

A Chocolatey configuration file looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="git" />
<package id="nodejs-lts" />
<package id="vscode" />
<package id="pyenv-win" />
<package id="visualstudio2022community" />
<package id="visualstudio2022-workload-nativedesktop" />
<package id="electron" />
</packages>

Running choco install chocolatey.config is the equivalent of calling choco install <id> for every package in the file.

Python on Windows (pyenv)

Installing and managing Python on Windows is a notoriously difficult task even for advanced developers. It is best practice to have exactly 1 tool for managing python on your system, which is a rule for most things in software development (this is what npm does for node packages). We highly recommend uninstalling Python and using pyenv even if you never anticipate using python again. We promise the extra setup today will pay great dividends in the future!

First and foremost, turn off both Python App Installers in the "App Execution Aliases" settings. Please complete this step even if you already have a Python manager

App execution aliases -Turn off app installer

Now we can set up our python management system1. We recommend pyenv as it is small and intuitive for newer developers. It lets us install python globally AND switch between different versions for individual projects. It does this (and only this) extremely well. Complete the following steps to install pyenv for Windows and set up your global python environment:

  1. Ensure Python is completely uninstalled from your system2

    • Type python on the command line and ensure you get a "Command 'python' not found" error

      python
    • If the command executes, locate the installation (check "Add or Remove programs" in the settings) and remove it. Continue until the error appears

    • If the Microsoft Store launches check again to ensure "Manage App execution aliases" is turned off for python.exe and python3.exe

  2. Install pyenv-win

    • pyenv-win will install with chocolatey.config - enter pyenv on the command line to see if it's already on your system. You should see a list of commands printed to your terminal.

      pyenv
    • If not:

      choco install pyenv-win
  3. Install your python version

    pyenv install <version>
    • If you're using a different Python version for another project that version will work fine so long as it is at least version > 3.0.0

    • Otherwise install the newest version that includes exactly 3 numbers, e.g. 3.10.6

      pyenv install --list
  4. Use that version as your global install

    pyenv global <version>
1_If you are already using [Anaconda](https://www.anaconda.com) for Python and it's various other tools that is okay! You already have python manager installed on your system and can skip this section._2_Any "solo" installations can and will cause major conflicts with `pyenv`. It can cause issues when you try to change your version, when another program checks for python, when you update Windows... so on and so forth. Perhaps you've already run into something unexpected like this! This is why it's essential python is completely uninstalled from your computer before beginning._

Manual Installation (Windows)

Linux

We recommend using Ubuntu (18.10 or later) as your distro but any distro new enough to support GLIBC_2.28 should work.

Further Help

If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

- - +
Version: 3.0.0

Setup Details

Prerequisites

It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. First we need the following programs

  • git (version control and GitHub integration)
  • nodejs (web development - we recommend the latest long term support version)
  • python (3.7 or later)
  • An Integrated Development Environment (we recommend VS Code)

In addition, Honeycomb relies on Electron to package the cross-platform desktop applications. Some of electron's prerequisites are platform dependant - listed below are the prerequisites for each operating system along with resources for manually installing them.

MacOS

Brew

All of the required dependencies for honeycomb on MacOS can be installed via the brewfile. See the quick start for more information.

Manual Installation (MacOS)

Windows

Note that Windows occasionally requires a restart after package installations complete. If you are running into issues after installing the packages please restart your terminal and/or your entire computer. This should resolve most issues.

chocolatey

chocolatey.config

A Chocolatey configuration file looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="git" />
<package id="nodejs-lts" />
<package id="vscode" />
<package id="pyenv-win" />
<package id="visualstudio2022community" />
<package id="visualstudio2022-workload-nativedesktop" />
<package id="electron" />
</packages>

Running choco install chocolatey.config is the equivalent of calling choco install <id> for every package in the file.

Python on Windows (pyenv)

Installing and managing Python on Windows is a notoriously difficult task even for advanced developers. It is best practice to have exactly 1 tool for managing python on your system, which is a rule for most things in software development (this is what npm does for node packages). We highly recommend uninstalling Python and using pyenv even if you never anticipate using python again. We promise the extra setup today will pay great dividends in the future!

First and foremost, turn off both Python App Installers in the "App Execution Aliases" settings. Please complete this step even if you already have a Python manager

App execution aliases +Turn off app installer

Now we can set up our python management system1. We recommend pyenv as it is small and intuitive for newer developers. It lets us install python globally AND switch between different versions for individual projects. It does this (and only this) extremely well. Complete the following steps to install pyenv for Windows and set up your global python environment:

  1. Ensure Python is completely uninstalled from your system2

    • Type python on the command line and ensure you get a "Command 'python' not found" error

      python
    • If the command executes, locate the installation (check "Add or Remove programs" in the settings) and remove it. Continue until the error appears

    • If the Microsoft Store launches check again to ensure "Manage App execution aliases" is turned off for python.exe and python3.exe

  2. Install pyenv-win

    • pyenv-win will install with chocolatey.config - enter pyenv on the command line to see if it's already on your system. You should see a list of commands printed to your terminal.

      pyenv
    • If not:

      choco install pyenv-win
  3. Install your python version

    pyenv install <version>
    • If you're using a different Python version for another project that version will work fine so long as it is at least version > 3.0.0

    • Otherwise install the newest version that includes exactly 3 numbers, e.g. 3.10.6

      pyenv install --list
  4. Use that version as your global install

    pyenv global <version>
1_If you are already using [Anaconda](https://www.anaconda.com) for Python and it's various other tools that is okay! You already have python manager installed on your system and can skip this section._2_Any "solo" installations can and will cause major conflicts with `pyenv`. It can cause issues when you try to change your version, when another program checks for python, when you update Windows... so on and so forth. Perhaps you've already run into something unexpected like this! This is why it's essential python is completely uninstalled from your computer before beginning._

Manual Installation (Windows)

Linux

We recommend using Ubuntu (18.10 or later) as your distro but any distro new enough to support GLIBC_2.28 should work.

Further Help

If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

+ + \ No newline at end of file diff --git a/docs/3.0.0/troubleshooting/index.html b/docs/3.0.0/troubleshooting/index.html index 2bc5fe11..a251d4d3 100644 --- a/docs/3.0.0/troubleshooting/index.html +++ b/docs/3.0.0/troubleshooting/index.html @@ -3,14 +3,14 @@ -Troubleshooting | Honeycomb - - +Troubleshooting | Honeycomb + +
-
Version: 3.0.0

Troubleshooting

Inspecting Errors

When developing electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The react app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

In case you want to find out where the error is coming from when running the app locally:

  • Try reviewing logs in the terminal
  • Inspect element in your browser by openning your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.

Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild.

Testing in Linux

When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runer creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

This is a "known issue" with some test runners on Linux, as in discussions here and here.

One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

  • Command that initially fails with ENOSPC: npm test
  • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
  • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
  • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
  • Save, exit, and reload the config file: sudo sysctl -p
  • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
  • Retry the initial command, which should now succeed: npm test
- - +
Version: 3.0.0

Troubleshooting

Inspecting Errors

When developing electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The react app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

In case you want to find out where the error is coming from when running the app locally:

  • Try reviewing logs in the terminal
  • Inspect element in your browser by openning your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.

Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild.

Testing in Linux

When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runer creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

This is a "known issue" with some test runners on Linux, as in discussions here and here.

One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

  • Command that initially fails with ENOSPC: npm test
  • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
  • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
  • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
  • Save, exit, and reload the config file: sudo sysctl -p
  • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
  • Retry the initial command, which should now succeed: npm test
+ + \ No newline at end of file diff --git a/docs/3.0.0/variants/index.html b/docs/3.0.0/variants/index.html index f4deb6ae..140dd980 100644 --- a/docs/3.0.0/variants/index.html +++ b/docs/3.0.0/variants/index.html @@ -3,14 +3,14 @@ -Variants | Honeycomb - - +Variants | Honeycomb + +
-
Version: 3.0.0

Variants

Variant Specific Executables

In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

Windows:

"package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
"postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

Mac:

"package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
"installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

Linux:

"package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
"postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

Variant Specific Workflows

In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

variant: [<comma_separated_list_of_variant_names>]

Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

- name: Load .env file for variant
uses: xom9ikk/dotenv@v1.0.2
with:
path: ./env
mode: ${{matrix.variant}}

In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

- name: package electron - windows
if: startsWith(matrix.os, 'windows')
run: npm run package:windows:${{ matrix.variant }}
- name: package electron - linux
if: startsWith(matrix.os, 'ubuntu')
run: npm run package:linux:${{ matrix.variant }}
- name: package electron - mac
if: startsWith(matrix.os, 'mac')
run: npm run package:mac:${{ matrix.variant }}
- name: npm rebuild - mac
if: startsWith(matrix.os, 'mac')
run: npm rebuild
- name: Mac installer
if: startsWith(matrix.os, 'mac')
run: npm run installer:mac:${{ matrix.variant }}

Replace the # Upload installers to github action section in package.yaml with the following code:

- name: upload win-installer
uses: actions/upload-artifact@master
if: startsWith(matrix.os, 'windows')
with:
name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
- name: upload mac-installer
uses: actions/upload-artifact@master
if: startsWith(matrix.os, 'mac')
with:
name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
- name: upload linux-installer
uses: actions/upload-artifact@master
if: startsWith(matrix.os, 'ubuntu')
with:
name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

Replace the # Upload installers to github release section in release.yaml with the following code:

- name: Upload app to release - windows
if: startsWith(matrix.os, 'windows')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
tag: ${{ github.ref }}
- name: Upload app to release - linux
if: startsWith(matrix.os, 'ubuntu')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
tag: ${{ github.ref }}
- name: Upload app to release - mac
if: startsWith(matrix.os, 'mac')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
tag: ${{ github.ref }}
- - +
Version: 3.0.0

Variants

Variant Specific Executables

In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

Windows:

"package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
"postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

Mac:

"package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
"installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

Linux:

"package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
"postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

Variant Specific Workflows

In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

variant: [<comma_separated_list_of_variant_names>]

Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

- name: Load .env file for variant
uses: xom9ikk/dotenv@v1.0.2
with:
path: ./env
mode: ${{matrix.variant}}

In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

- name: package electron - windows
if: startsWith(matrix.os, 'windows')
run: npm run package:windows:${{ matrix.variant }}
- name: package electron - linux
if: startsWith(matrix.os, 'ubuntu')
run: npm run package:linux:${{ matrix.variant }}
- name: package electron - mac
if: startsWith(matrix.os, 'mac')
run: npm run package:mac:${{ matrix.variant }}
- name: npm rebuild - mac
if: startsWith(matrix.os, 'mac')
run: npm rebuild
- name: Mac installer
if: startsWith(matrix.os, 'mac')
run: npm run installer:mac:${{ matrix.variant }}

Replace the # Upload installers to github action section in package.yaml with the following code:

- name: upload win-installer
uses: actions/upload-artifact@master
if: startsWith(matrix.os, 'windows')
with:
name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
- name: upload mac-installer
uses: actions/upload-artifact@master
if: startsWith(matrix.os, 'mac')
with:
name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
- name: upload linux-installer
uses: actions/upload-artifact@master
if: startsWith(matrix.os, 'ubuntu')
with:
name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

Replace the # Upload installers to github release section in release.yaml with the following code:

- name: Upload app to release - windows
if: startsWith(matrix.os, 'windows')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
tag: ${{ github.ref }}
- name: Upload app to release - linux
if: startsWith(matrix.os, 'ubuntu')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
tag: ${{ github.ref }}
- name: Upload app to release - mac
if: startsWith(matrix.os, 'mac')
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
tag: ${{ github.ref }}
+ + \ No newline at end of file diff --git a/docs/3.0.0/version_control/index.html b/docs/3.0.0/version_control/index.html index aa324197..c3bca72a 100644 --- a/docs/3.0.0/version_control/index.html +++ b/docs/3.0.0/version_control/index.html @@ -3,15 +3,15 @@ -Version Control | Honeycomb - - +Version Control | Honeycomb + +
-
Version: 3.0.0

Version Control

Git Overview

Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

Nearly all operations that are performed by Git are in you local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below.

Git basics

If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

Example branch

Comment styles

We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

Cheatsheet

CommandBrief
git add <files>add a file to next commit (stage)
git commit -m <message>commit staged files
git pushupload staged commit to repo
git pullget remote repo commits and download (try and resolve conflicts)
git clone <url>download entire repository
git checkout <branch>checkout and create the branch you want to use
# create branch with your feature
git checkout -b feature_name
# check the status of your repositoey
git status
# commit file contents to the local repository
git commit -am "My feature is ready"
# specific message
# push file contents to the remote (i.e. cloud) repository
git push origin feature_name

Alternative options

Instead of using commands in the terminal, you can also download GitHub desktop. It is very intuitive to use.

Clone repository

git clone

Select a branch or create a new branch

git branch

Commit changes and push

git commit

Create a Pull Request

Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

git pr

git pr info

Best Practices

Git Workflow

We recommend using a simple flow based on following rules:

  • Use topic/feature branches, no direct commits on main.
  • Perform tests and code reviews before merges into main, not afterwards.
  • Every branch starts from main, and targets main.
  • Commit messages reflect intent.

Git Branches

  • main is the default branch and where releases are made off. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches
  • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button

This flow is sometimes referred to as Feature Branch Workflow

Stay up-to-date with Honeycomb template repo

Honeycomb is an active project, and will be updated with new features over time. To bring changes from the honeycomb template repository to -your task, follow the following steps:

Add honeycomb as an additional remote

By default, your repository is configured to only sync with your remote, which typically is referred to as origin. You can add Honeycomb as an additional remote as follows:

git remote add honeycomb https://github.com/brown-ccv/honeycomb.git

Adding a remote is a one time operation. At that point you can pull content from the honeycomb remote as follows:

git fetch --all
git merge honeycomb/main --allow-unrelated histories

If there are any conflicts, you'll need to resolve those, then commit the merge:

git commit -a -m "merge honeycomb latest"
- - +
Version: 3.0.0

Version Control

Git Overview

Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

Nearly all operations that are performed by Git are in you local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below.

Git basics

If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

Example branch

Comment styles

We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

Cheatsheet

CommandBrief
git add <files>add a file to next commit (stage)
git commit -m <message>commit staged files
git pushupload staged commit to repo
git pullget remote repo commits and download (try and resolve conflicts)
git clone <url>download entire repository
git checkout <branch>checkout and create the branch you want to use
# create branch with your feature
git checkout -b feature_name
# check the status of your repositoey
git status
# commit file contents to the local repository
git commit -am "My feature is ready"
# specific message
# push file contents to the remote (i.e. cloud) repository
git push origin feature_name

Alternative options

Instead of using commands in the terminal, you can also download GitHub desktop. It is very intuitive to use.

Clone repository

git clone

Select a branch or create a new branch

git branch

Commit changes and push

git commit

Create a Pull Request

Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

git pr

git pr info

Best Practices

Git Workflow

We recommend using a simple flow based on following rules:

  • Use topic/feature branches, no direct commits on main.
  • Perform tests and code reviews before merges into main, not afterwards.
  • Every branch starts from main, and targets main.
  • Commit messages reflect intent.

Git Branches

  • main is the default branch and where releases are made off. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches
  • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button

This flow is sometimes referred to as Feature Branch Workflow

Stay up-to-date with Honeycomb template repo

Honeycomb is an active project, and will be updated with new features over time. To bring changes from the honeycomb template repository to +your task, follow the following steps:

Add honeycomb as an additional remote

By default, your repository is configured to only sync with your remote, which typically is referred to as origin. You can add Honeycomb as an additional remote as follows:

git remote add honeycomb https://github.com/brown-ccv/honeycomb.git

Adding a remote is a one time operation. At that point you can pull content from the honeycomb remote as follows:

git fetch --all
git merge honeycomb/main --allow-unrelated histories

If there are any conflicts, you'll need to resolve those, then commit the merge:

git commit -a -m "merge honeycomb latest"
+ + \ No newline at end of file diff --git a/docs/3.1.x/ci/index.html b/docs/3.1.x/ci/index.html index 3fd3f616..d7ac30d8 100644 --- a/docs/3.1.x/ci/index.html +++ b/docs/3.1.x/ci/index.html @@ -3,14 +3,14 @@ -Continuous Integration | Honeycomb - - +Continuous Integration | Honeycomb + +
-
Version: 3.1.x

Continuous Integration

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD?

CI/CD refers to Continuous Integration and either Continuous Delivery or Continuous Deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

GitHub Actions are written as YML files inside a .github/workflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows, Mac and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds a PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their [official documentation](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions).

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file, install, and run.

The executable does not require installation of any additional software.

- - +
Version: 3.1.x

Continuous Integration

Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings on demand or automatically as the code is pushed to the repository. In this section, we provide a short introduction to definitions. We explain the GitHub Actions included with Honeycomb. These workflows should provide a foundation but can easily be modified or extended to meet more needs.

What is CI/CD?

CI/CD refers to Continuous Integration and either Continuous Delivery or Continuous Deployment. CI/CD enforces the automated building of bundled executables so that tasks can be easily installed without dependencies. In Honeycomb, CI/CD is managed by GitHub Actions.

What are Github Actions

GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

GitHub Actions are written as YML files inside a .github/workflows/ folder in your repository.

Building the executables

Honeycomb includes workflows to build and create installers for Windows, Mac and Linux. These workflows exist for two configurations of the tasks:

  • Home: The app does not expect event code triggers and photodiode spots.
  • Clinic: The app expects event code triggers and photodiode spots.

More specifically, the following workflows are included:

  • build.yaml: Every time an Pull Request (PR) is opened, or a push is made to the main branch, the software is built and tests are run for all platforms and home and clinic settings. This workflow does not build and upload desktop installers
  • package.yaml: Create installers for any/all platforms for the home and clinic setting on demand 1. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.
  • release.yml: Every time a Tag is released, installers are created and uploaded as packages. This also builds a PsiTurk version, and deploys to GitHub pages a web version of the application.
1 On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their [official documentation](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions#about-billing-for-github-actions).

Download your bundled executable to install and run your task

You can download the executable file from either the tagged release page or the GitHub actions page. To install, unzip the downloaded file, install, and run.

The executable does not require installation of any additional software.

+ + \ No newline at end of file diff --git a/docs/3.1.x/deploy_online/index.html b/docs/3.1.x/deploy_online/index.html index 5067bd82..b23c1903 100644 --- a/docs/3.1.x/deploy_online/index.html +++ b/docs/3.1.x/deploy_online/index.html @@ -3,18 +3,18 @@ -Deploy online | Honeycomb - - +Deploy online | Honeycomb + +
-
Version: 3.1.x

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk-specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. +

Version: 3.1.x

Deploy online

Usage with PsiTurk

While this set up is optimized for Electron, we added functionality that will make use with PsiTurk easy. The application will detect if it's being used in a Turk environment and will:

  • Save the data to the default PsiTurk SQLite database.
  • Switch the language to Turk specific, if src/language/<locale>.mturk.json exists.
  • Use the Turk-specific timeline if different than the primary timeline.

Prebuilt version

When GitHub Actions is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts (skip next step if using). The workflows responsible for building the PsiTurk application are .github/workflows/package-home-all.yml and .github/workflows/release-home-all.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

Build instructions

To set up your PsiTurk project, we provide a script that does the conversion. PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

  • Build the application: npm run build

  • Move to the psiturkit directory: cd psiturkit

  • If it's the first time you're running the script:
    ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>

  • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):
    ./psiturk-it -u -p <PATH_TO_NEW_PSITURK_PROJECT>

Running PsiTurk

After that, just navigate to your newly created PsiTurk project directory.

shell> psiturk #start psiturk
psiturk> server on #start server
psiturk> debug #debug mode

Running on the Web

Using Github Pages

Running npm run build generates static content into the build directory that can be served using any static contents hosting service. The workflow .github/workflows/release-home-all.yml uploads the build directory to the gh-branch to serve the application on GitHub pages as an example. After a creating a tag, the workflow will run and your application will be served at <github user>.github.io/<repository>. -For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.

  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.

  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.

  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.

  5. To create the secret, copy your private key (e.g., xclip -sel clip < ~/.ssh/id_rsa) and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.

  6. Make sure the publishing source for your repository is configured for gh-pages branch.

- - +For this step to succeed you will need to create a deploy key and enable GitHub Pages for your repository.

  1. Generate a new SSH key.

  2. By default, your public key should have been created in ~/.ssh/id_rsa.pub or use the name you've provided.

  3. Copy key to clipboard with xclip -sel clip < ~/.ssh/id_rsa.pub and paste it as a deploy key in your repository. Copy file content if the command line doesn't work for you. Check the box for Allow write access before saving your deployment key.

  4. You'll need your private key as a GitHub secret to allow the workflow to run the deployment for you.

  5. To create the secret, copy your private key (e.g., xclip -sel clip < ~/.ssh/id_rsa) and paste a GitHub secret with name GH_PAGES_DEPLOY. Copy file content if the command line doesn't work for you. Save your secret.

  6. Make sure the publishing source for your repository is configured for gh-pages branch.

+ + \ No newline at end of file diff --git a/docs/3.1.x/environment_variables/index.html b/docs/3.1.x/environment_variables/index.html index 3b1ffd16..34043b51 100644 --- a/docs/3.1.x/environment_variables/index.html +++ b/docs/3.1.x/environment_variables/index.html @@ -3,14 +3,14 @@ -Environment Variables | Honeycomb - - +Environment Variables | Honeycomb + +
-
Version: 3.1.x

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text. Optional variables are labeled with the optional badge and mandatory variables are labeled with the default <default-value> badge with their default value specified. The buildtime badge indicates the variable is used during the build/compilation phase (npm build) while the runtime badge indicates the variable is used during the executable run (npm run dev).

Dev Mode Only

  • ELECTRON_START_URL stringoptional: URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode.

Desktop Only

  • EVENT_MARKER_PRODUCT_IDstringoptionalruntime: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME stringoptionalruntime: The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_VIDEObooleandefault falsebuildtime: whether the participant is being video recorded. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_EEGbooleandefault falsebuildtime: whether the event marker/EEG is available. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_PHOTODIODEbooleandefault falsebuildtime: whether the photodiode is in use. This can be used when the task is running as a desktop app (electron).

Desktop and Online

  • REACT_APP_VOLUMEbooleandefault falsebuildtime: whether the participant is being asked to adjust volume. This can be used on both the desktop (electron) and online settings.
  • REACT_APP_PARTICIPANT_ID stringoptionalruntime: The default participant id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.
  • REACT_APP_STUDY_ID stringoptionalruntime: The default study id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.

Understanding Build-Time and Run-Time Variables

  • runtime: Run-time environment variables allow for quick changes before running the task. They are convenient since they don't require building a whole different executable. For a Desktop Application, these are set at the system level and must be available at the time where the task runs. See this tutorial for OS specific instructions.. For a Firebase Application, these must be stored in the Firestore.

  • build time: Build-time environment variables are configured before the application is built and cannot be changed at run-time. They are configured via .env files before building. Instead of using a single .env file, we prefer to define separate files under the env/ directory, and use a package called dotenv-cli before building`.

The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

package.json
"[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]:<env name>"

See NPM Scripts for more

- - +
Version: 3.1.x

Environment Variables

Honeycomb uses environment variables during build and run time to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text. Optional variables are labeled with the optional badge and mandatory variables are labeled with the default <default-value> badge with their default value specified. The buildtime badge indicates the variable is used during the build/compilation phase (npm build) while the runtime badge indicates the variable is used during the executable run (npm run dev).

Dev Mode Only

  • ELECTRON_START_URL stringoptional: URL (e.g. http://localhost:3000) where the front end of the app is being hosted - also used in electron.js to indicate the app is running in dev mode.

Desktop Only

  • EVENT_MARKER_PRODUCT_IDstringoptionalruntime: The product ID of the event marker (e.g. 0487). If not set, it will use the productID set in public/config/trigger.js if available, or attempt to connect using the com name.
  • EVENT_MARKER_COM_NAME stringoptionalruntime: The com name of the event marker (e.g. COM3). If not set, it will use the comName set in public/config/trigger.js. If the productID is set (not an empty string), this field will be ignored.
  • REACT_APP_VIDEObooleandefault falsebuildtime: whether the participant is being video recorded. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_EEGbooleandefault falsebuildtime: whether the event marker/EEG is available. This can be used when the task is running as a desktop app (electron).
  • REACT_APP_USE_PHOTODIODEbooleandefault falsebuildtime: whether the photodiode is in use. This can be used when the task is running as a desktop app (electron).

Desktop and Online

  • REACT_APP_VOLUMEbooleandefault falsebuildtime: whether the participant is being asked to adjust volume. This can be used on both the desktop (electron) and online settings.
  • REACT_APP_PARTICIPANT_ID stringoptionalruntime: The default participant id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.
  • REACT_APP_STUDY_ID stringoptionalruntime: The default study id to show when authorizing a participant. If not set, user will need to enter the value in the provided input box.

Understanding Build-Time and Run-Time Variables

  • runtime: Run-time environment variables allow for quick changes before running the task. They are convenient since they don't require building a whole different executable. For a Desktop Application, these are set at the system level and must be available at the time where the task runs. See this tutorial for OS specific instructions.. For a Firebase Application, these must be stored in the Firestore.

  • build time: Build-time environment variables are configured before the application is built and cannot be changed at run-time. They are configured via .env files before building. Instead of using a single .env file, we prefer to define separate files under the env/ directory, and use a package called dotenv-cli before building`.

The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

package.json
"[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]:<env name>"

See NPM Scripts for more

+ + \ No newline at end of file diff --git a/docs/3.1.x/event_triggers/index.html b/docs/3.1.x/event_triggers/index.html index f1a83fc3..1317615f 100644 --- a/docs/3.1.x/event_triggers/index.html +++ b/docs/3.1.x/event_triggers/index.html @@ -3,14 +3,14 @@ -Set up event triggers | Honeycomb - - +Set up event triggers | Honeycomb + +
-
Version: 3.1.x

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here.

Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

Send event code triggers

Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

- - +
Version: 3.1.x

Set up event triggers

BrainVision Trigger Box setup

Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

COMNAME

and set the COM port to the correct value (e.g., COM3).

Open Source Event Trigger setup

Details on how to make the open source event trigger and photodiode can be found here.

Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

Send event code triggers

Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper eventCode (e.g. eventCode.Fixation) as input.

Run the task with event triggers

Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

+ + \ No newline at end of file diff --git a/docs/3.1.x/firebase/index.html b/docs/3.1.x/firebase/index.html index 26a1e2d8..a6bf3ac7 100644 --- a/docs/3.1.x/firebase/index.html +++ b/docs/3.1.x/firebase/index.html @@ -3,15 +3,15 @@ -Firebase | Honeycomb - - +Firebase | Honeycomb + +
-
Version: 3.1.x

Firebase

Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

Setting up Firebase

info

Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

Adding Products

First we'll configure Firebase Hosting and Cloud Firestore on your project.

  1. Log in to Firebase with your Google account on the Firebase console.

  2. Navigate to your project from the console

  3. Register a new web app to your project (Register your app)

    note

    We recommend giving your web app the same name as your task's repository

  4. Add Firestore Database to your project (Create a Cloud Firestore database)

    note

    Chose production mode for the starting mode and the default "Cloud Firestore Location"

The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

Installing the Command Line Interface

The Firebase CLI can be installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

Install the Firebase CLI
npm install -g firebase-tools
Login to Firebase
firebase login

A "command not found" error usually indicates firebase-tools has not been installed correctly

Connecting Your Firebase Project

  1. Change the default project name of your task in .firebaserc
.firebaserc
{
"projects": {
"default": "<your project name>"
}
}
  1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

    1. Return to your project on the Firebase console.

    2. Navigate to your project setting

      Firebase project settings
    3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

      Firebase web credentials

      env/.env.firebase
      REACT_APP_FIREBASE="true"
      REACT_APP_apiKey=
      REACT_APP_authDomain=
      REACT_APP_projectId=
      REACT_APP_storageBucket=
      REACT_APP_messagingSenderId=
      REACT_APP_appId=

      Additional variables may be present in the console, they do not need to be copied.

  2. Deploy the default Firestore security rules

Deploy Firestore rules
firebase deploy --only firestore:rules

Your task is now connected to an initialized Firebase project!

Registering Studies

caution

This step must be followed exactly. See Security Rules for more information.

  1. Navigate to your Firestore Database in the console.
  2. Click "Start collection"
  3. Enter registered_studies for the collection id and click "next"
  4. Enter the id of your study for the document id
  5. Add a field named registered_participants with the type "array"
  6. Add the id of each study participant as a string inside the array
Create a study

The study should like this when you're finished:

Example study

Additional studies must be created inside the registered_studies collection

Developing With Firebase

Two terminal windows must be used while developing for Firebase. Instructions splitting terminals in VSCode can be found here.

Run Honeycomb with Firebase Enabled
npm run dev:firebase
Start the Firebase Emulators
npm run firebase:emulators:start

Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. -That data can be viewed at http://localhost:4000/firestore.

info

Honeycomb populates the Firestore emulators with the study s1 and participant p1.

Deploying on Firebase

Firebase deployments are handled automatically following Continuous Integration Continuous Development practices using GitHub Actions. Here we will connect create custom actions that are connected to the task's Firebase project.

Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

Initialize Firebase hosting via Github actions
firebase init hosting:github
  1. The window should log you in automatically. If not, follow the prompts to log in with the same account you used in the console.
  2. <username>/<repository name> refers to the name of your repository in Github. Be sure it's typed correctly!
  3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
  4. Enter npm install && npm run build:firebase for the prompt "What script should be run before every deploy?"
  5. Enter y to overwrite the current workflow file
  6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
  7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
  8. Enter y to overwrite the current workflow file

Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Ensure the correct run script is present in both files.

Github actions created by firebase

Downloading Data

Honeycomb ships with a script for downloading data from Firebase onto a computer. A local service account must be created in order to use it.

Setting up a Service Account

Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

  1. Return to the project settings your project on the Firebase console.

    Firebase project settings
  2. Click on the "Service accounts" tab

  3. Near the bottom, click "Generate new Private key" and "Generate Key"

  4. Rename the key firebase-service-account.json and move it to the root directory of your task. Be sure the file looks grayed out and is not picked up by git!

danger

A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

Using the Download Script

Honeycomb comes with a download script. It will programmatically access Firestore to download the experiment data you choose

Script Usage
npm run firebase:download -- <studyID> <participantID> [sessionNumber] [outputRoot]
  • studyID: The ID of a given study
  • participantID: The ID of a given participant on the studyID study
  • sessionNumber: Optional number to select which session to download, defaults to the most recent session
  • outputRoot: Optional path to the folder where data should be saved, defaults to the current folder

Running the script without sessionNumber list all of the available sessions. For example:

Found 3 sessions:
0: 2022-07-26T22:04:55.544Z
1: 2022-07-27T14:16:36.301Z
2: 2022-07-27T19:56:26.229Z

sessionNumber

Adding a sessionNumber will download that sessions data:

Download data for session 2022-07-26T22:04:55.544Z
npm run firebase:download -- <studyID> <participantID> 0 [outputRoot]

outputRoot

Session data is stored in the current directory by default. The folders and file name are chosen to avoid naming collisions: ./participant_responses/<studyID>/<participantID>/<sessionID>.json

Adding an outputRoot will download that data in a custom location:

Download data for session 2022-07-26T22:04:55.544Z at /path/to/my/data
npm run firebase:download -- <studyID> <participantID> 0 /path/to/my/data

This will result in data saved to /path/to/my/data/participant_responses/<studyID>/<participantID>/<sessionID>.json

Further Reading

The Firebase Documentation details its Emulator Suite in much greater detail.

Security Rules

Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /participant_responses/{studyID}/participants/{participantID} {
allow create, read:
if participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;
// ...
}
}
}

Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

Line 6 defines our rule - it must pass for Honeycomb to connect to the document. participantID must be found in an array called registered_participants inside of a document at /databases/{database}/documents/registered_studies/{studyID}.

Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must manually make these changes from the Firestore console.

danger

Firestore rules must define every match pattern in your project. Attempting to connect anywhere other than /participant_responses/{studyID}/participants/{participantID} will be automatically denied even if you add other collections to your database. This is why firestore.rules contains additional nested rules - these should be left alone.

- - +
Version: 3.1.x

Firebase

Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

Setting up Firebase

info

Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

Adding Products

First we'll configure Firebase Hosting and Cloud Firestore on your project.

  1. Log in to Firebase with your Google account on the Firebase console.

  2. Navigate to your project from the console

  3. Register a new web app to your project (Register your app)

    note

    We recommend giving your web app the same name as your task's repository

  4. Add Firestore Database to your project (Create a Cloud Firestore database)

    note

    Chose production mode for the starting mode and the default "Cloud Firestore Location"

The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

Installing the Command Line Interface

The Firebase CLI can be installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

Install the Firebase CLI
npm install -g firebase-tools
Login to Firebase
firebase login

A "command not found" error usually indicates firebase-tools has not been installed correctly

Connecting Your Firebase Project

  1. Change the default project name of your task in .firebaserc
.firebaserc
{
"projects": {
"default": "<your project name>"
}
}
  1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

    1. Return to your project on the Firebase console.

    2. Navigate to your project setting

      Firebase project settings
    3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

      Firebase web credentials

      env/.env.firebase
      REACT_APP_FIREBASE="true"
      REACT_APP_apiKey=
      REACT_APP_authDomain=
      REACT_APP_projectId=
      REACT_APP_storageBucket=
      REACT_APP_messagingSenderId=
      REACT_APP_appId=

      Additional variables may be present in the console, they do not need to be copied.

  2. Deploy the default Firestore security rules

Deploy Firestore rules
firebase deploy --only firestore:rules

Your task is now connected to an initialized Firebase project!

Registering Studies

caution

This step must be followed exactly. See Security Rules for more information.

  1. Navigate to your Firestore Database in the console.
  2. Click "Start collection"
  3. Enter registered_studies for the collection id and click "next"
  4. Enter the id of your study for the document id
  5. Add a field named registered_participants with the type "array"
  6. Add the id of each study participant as a string inside the array
Create a study

The study should like this when you're finished:

Example study

Additional studies must be created inside the registered_studies collection

Developing With Firebase

Two terminal windows must be used while developing for Firebase. Instructions splitting terminals in VSCode can be found here.

Run Honeycomb with Firebase Enabled
npm run dev:firebase
Start the Firebase Emulators
npm run firebase:emulators:start

Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. +That data can be viewed at http://localhost:4000/firestore.

info

Honeycomb populates the Firestore emulators with the study s1 and participant p1.

Deploying on Firebase

Firebase deployments are handled automatically following Continuous Integration Continuous Development practices using GitHub Actions. Here we will connect create custom actions that are connected to the task's Firebase project.

Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

Initialize Firebase hosting via Github actions
firebase init hosting:github
  1. The window should log you in automatically. If not, follow the prompts to log in with the same account you used in the console.
  2. <username>/<repository name> refers to the name of your repository in Github. Be sure it's typed correctly!
  3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
  4. Enter npm install && npm run build:firebase for the prompt "What script should be run before every deploy?"
  5. Enter y to overwrite the current workflow file
  6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
  7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
  8. Enter y to overwrite the current workflow file

Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Ensure the correct run script is present in both files.

Github actions created by firebase

Downloading Data

Honeycomb ships with a script for downloading data from Firebase onto a computer. A local service account must be created in order to use it.

Setting up a Service Account

Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

  1. Return to the project settings your project on the Firebase console.

    Firebase project settings
  2. Click on the "Service accounts" tab

  3. Near the bottom, click "Generate new Private key" and "Generate Key"

  4. Rename the key firebase-service-account.json and move it to the root directory of your task. Be sure the file looks grayed out and is not picked up by git!

danger

A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

Using the Download Script

Honeycomb comes with a download script. It will programmatically access Firestore to download the experiment data you choose

Script Usage
npm run firebase:download -- <studyID> <participantID> [sessionNumber] [outputRoot]
  • studyID: The ID of a given study
  • participantID: The ID of a given participant on the studyID study
  • sessionNumber: Optional number to select which session to download, defaults to the most recent session
  • outputRoot: Optional path to the folder where data should be saved, defaults to the current folder

Running the script without sessionNumber list all of the available sessions. For example:

Found 3 sessions:
0: 2022-07-26T22:04:55.544Z
1: 2022-07-27T14:16:36.301Z
2: 2022-07-27T19:56:26.229Z

sessionNumber

Adding a sessionNumber will download that sessions data:

Download data for session 2022-07-26T22:04:55.544Z
npm run firebase:download -- <studyID> <participantID> 0 [outputRoot]

outputRoot

Session data is stored in the current directory by default. The folders and file name are chosen to avoid naming collisions: ./participant_responses/<studyID>/<participantID>/<sessionID>.json

Adding an outputRoot will download that data in a custom location:

Download data for session 2022-07-26T22:04:55.544Z at /path/to/my/data
npm run firebase:download -- <studyID> <participantID> 0 /path/to/my/data

This will result in data saved to /path/to/my/data/participant_responses/<studyID>/<participantID>/<sessionID>.json

Further Reading

The Firebase Documentation details its Emulator Suite in much greater detail.

Security Rules

Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /participant_responses/{studyID}/participants/{participantID} {
allow create, read:
if participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;
// ...
}
}
}

Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

Line 6 defines our rule - it must pass for Honeycomb to connect to the document. participantID must be found in an array called registered_participants inside of a document at /databases/{database}/documents/registered_studies/{studyID}.

Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must manually make these changes from the Firestore console.

danger

Firestore rules must define every match pattern in your project. Attempting to connect anywhere other than /participant_responses/{studyID}/participants/{participantID} will be automatically denied even if you add other collections to your database. This is why firestore.rules contains additional nested rules - these should be left alone.

+ + \ No newline at end of file diff --git a/docs/3.1.x/index.html b/docs/3.1.x/index.html index d6096bb6..8ed2a4df 100644 --- a/docs/3.1.x/index.html +++ b/docs/3.1.x/index.html @@ -3,14 +3,14 @@ -Introduction | Honeycomb - - +Introduction | Honeycomb + +
-
Version: 3.1.x

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy-to-install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych 7 tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

Community Driven

Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

Cite this work

If you use Honeycomb in your work, please cite

Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

- - +
Version: 3.1.x

Introduction

Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

Flexible deployment online and in the lab

Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

Easy-to-install executables

Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

Foundation in jsPsych

jsPsych 7 tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

Community Driven

Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

Cite this work

If you use Honeycomb in your work, please cite

Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

+ + \ No newline at end of file diff --git a/docs/3.1.x/javascript/index.html b/docs/3.1.x/javascript/index.html index 018fd277..b8161389 100644 --- a/docs/3.1.x/javascript/index.html +++ b/docs/3.1.x/javascript/index.html @@ -3,14 +3,14 @@ -JavaScript | Honeycomb - - +JavaScript | Honeycomb + +
-
Version: 3.1.x

JavaScript

Learning JavaScript

The Mozilla Developer Network Web Docs is the gold standard for programming on the web. The JavaScript page is an excellent place for further reading about JavaScript.

Interactive Tutorials

Learn JavaScript is an excellent platform for beginning to learn the JavaScript programming language. It is full of interactive tutorials and small projects.

- - +
Version: 3.1.x

JavaScript

Learning JavaScript

The Mozilla Developer Network Web Docs is the gold standard for programming on the web. The JavaScript page is an excellent place for further reading about JavaScript.

Interactive Tutorials

Learn JavaScript is an excellent platform for beginning to learn the JavaScript programming language. It is full of interactive tutorials and small projects.

+ + \ No newline at end of file diff --git a/docs/3.1.x/npm_scripts/index.html b/docs/3.1.x/npm_scripts/index.html index b41b6ed1..2d5c46a3 100644 --- a/docs/3.1.x/npm_scripts/index.html +++ b/docs/3.1.x/npm_scripts/index.html @@ -3,14 +3,14 @@ -NPM Scripts | Honeycomb - - +NPM Scripts | Honeycomb + +
-
Version: 3.1.x

NPM Scripts

Node package manager (NPM) ships with functionality to combine common shell commands into custom scripts. These scripts are defined in package.json. All of the commands needed to develop, build, and deploy Honeycomb are written out as scripts.

Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

Scripts are run using the following terminal command:

npm run <script>

Start

  • electron starts an electron process with the built application.
  • electron-dev starts an electron process with the current code.
    • Note that the script waits for http://localhost:3000 to be available before launching the electron process.
  • start runs the app in development mode and does NOT open a browser. This makes working with electron easier as it creates its own browser for development.
  • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.

Firebase

  • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/
  • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/
    caution

    There's no way to revert to what used to be in `emulator_data/ once it's overwritten!

  • firebase:download runs the firebase-download-script.js script, saving certain data in Firebase to your local machine.

Dev

npm run dev runs the task in development mode on Electron. It executes npm start and npm run electron-dev concurrently.

Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your task.

  • dev:home executes npm run dev with equipment disabled (env/.env.home)
  • dev:home:video executes npm run dev with equipment disabled (env/.env.home) and video enabled (env/.env.video)
  • dev:clinic executes npm run dev with equipment enabled (env/.env.clinic)
  • dev:clinic:video executes npm run dev with equipment enabled (env/.env.clinic) and video enabled (env/.env.video)
  • dev:firebase executes npm run start:browser with Firebase enabled (env/.env.firebase)
    info

    firebase:emulators:start must be run in its own terminal in order for npm run firebase:dev to work

Build

npm run build creates a production build of the app in the build/ folder. Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your task.

  • dev:home executes npm run build with equipment disabled (env/.env.home)
  • dev:home:video executes npm run build with equipment disabled (env/.env.home) and video enabled (env/.env.video)
  • dev:clinic executes npm run build with equipment enabled (env/.env.clinic)
  • dev:clinic:video executes npm run build with equipment enabled (env/.env.clinic) and video enabled (env/.env.video)
  • dev:firebase executes npm run build with Firebase enabled (env/.env.firebase)

Package

npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

  • npm run package:windows
  • npm run package:linux
  • npm run package:mac
note

Packaging for windows on a non-windows machine requires mono and wine to be installed.

Miscellaneous

  • commit runs commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
  • lint uses Eslint to find problems in the code
  • format uses Eslint to find and fix problems in the code that it can automatically
  • test launches the test runner in the interactive watch mode. See running tests for more information.
- - +
Version: 3.1.x

NPM Scripts

Node package manager (NPM) ships with functionality to combine common shell commands into custom scripts. These scripts are defined in package.json. All of the commands needed to develop, build, and deploy Honeycomb are written out as scripts.

Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

Scripts are run using the following terminal command:

npm run <script>

Start

  • electron starts an electron process with the built application.
  • electron-dev starts an electron process with the current code.
    • Note that the script waits for http://localhost:3000 to be available before launching the electron process.
  • start runs the app in development mode and does NOT open a browser. This makes working with electron easier as it creates its own browser for development.
  • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.

Firebase

  • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/
  • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/
    caution

    There's no way to revert to what used to be in `emulator_data/ once it's overwritten!

  • firebase:download runs the firebase-download-script.js script, saving certain data in Firebase to your local machine.

Dev

npm run dev runs the task in development mode on Electron. It executes npm start and npm run electron-dev concurrently.

Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your task.

  • dev:home executes npm run dev with equipment disabled (env/.env.home)
  • dev:home:video executes npm run dev with equipment disabled (env/.env.home) and video enabled (env/.env.video)
  • dev:clinic executes npm run dev with equipment enabled (env/.env.clinic)
  • dev:clinic:video executes npm run dev with equipment enabled (env/.env.clinic) and video enabled (env/.env.video)
  • dev:firebase executes npm run start:browser with Firebase enabled (env/.env.firebase)
    info

    firebase:emulators:start must be run in its own terminal in order for npm run firebase:dev to work

Build

npm run build creates a production build of the app in the build/ folder. Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your task.

  • dev:home executes npm run build with equipment disabled (env/.env.home)
  • dev:home:video executes npm run build with equipment disabled (env/.env.home) and video enabled (env/.env.video)
  • dev:clinic executes npm run build with equipment enabled (env/.env.clinic)
  • dev:clinic:video executes npm run build with equipment enabled (env/.env.clinic) and video enabled (env/.env.video)
  • dev:firebase executes npm run build with Firebase enabled (env/.env.firebase)

Package

npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

  • npm run package:windows
  • npm run package:linux
  • npm run package:mac
note

Packaging for windows on a non-windows machine requires mono and wine to be installed.

Miscellaneous

  • commit runs commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
  • lint uses Eslint to find problems in the code
  • format uses Eslint to find and fix problems in the code that it can automatically
  • test launches the test runner in the interactive watch mode. See running tests for more information.
+ + \ No newline at end of file diff --git a/docs/3.1.x/prerequisites/index.html b/docs/3.1.x/prerequisites/index.html index 4f543880..b641e9af 100644 --- a/docs/3.1.x/prerequisites/index.html +++ b/docs/3.1.x/prerequisites/index.html @@ -3,14 +3,14 @@ -Prerequisites | Honeycomb - - +Prerequisites | Honeycomb + +
-
Version: 3.1.x

Prerequisites

It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install, this page details what programs and packages are needed to run and build Honeycomb. There are some OS specific prerequisites needed to build a task as a desktop application.

OS Independent

Git

git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

Node Version Manager

NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

Python

Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

note

Honeycomb needs version 3.7 or later to run - the installers use version 3.11.

Oracle JDk

Java is another high-level programming languages that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

note

Honeycomb needs version 11 or later to run - the installers use version 18.

Visual Studio Code

Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

Mac-specific Installs

X-Code

XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

Installing XCode
  xcode-select --install

Rosetta

Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple silicon system.

Windows-specific Install

Visual Studio

Visual Studio is a special IDE for the Windows platform. It comes with everything needed to compile desktop applications from a PC. Visual Studio Community is a free to use platform.

caution

The "Desktop development with C++" workload must also be installed with Visual Studio. The automated installers should preselect this but you should double check to be certain!

Manual Installation (macOS)

The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

Manual Installation (Windows)

The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

Manual Installation (Linux)

The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

Further Help

If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

- - +
Version: 3.1.x

Prerequisites

It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install, this page details what programs and packages are needed to run and build Honeycomb. There are some OS specific prerequisites needed to build a task as a desktop application.

OS Independent

Git

git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

Node Version Manager

NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

Python

Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

note

Honeycomb needs version 3.7 or later to run - the installers use version 3.11.

Oracle JDk

Java is another high-level programming languages that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

note

Honeycomb needs version 11 or later to run - the installers use version 18.

Visual Studio Code

Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

Mac-specific Installs

X-Code

XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

Installing XCode
  xcode-select --install

Rosetta

Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple silicon system.

Windows-specific Install

Visual Studio

Visual Studio is a special IDE for the Windows platform. It comes with everything needed to compile desktop applications from a PC. Visual Studio Community is a free to use platform.

caution

The "Desktop development with C++" workload must also be installed with Visual Studio. The automated installers should preselect this but you should double check to be certain!

Manual Installation (macOS)

The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

Manual Installation (Windows)

The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

Manual Installation (Linux)

The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

Further Help

If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

+ + \ No newline at end of file diff --git a/docs/3.1.x/project_organization/index.html b/docs/3.1.x/project_organization/index.html index be819b08..e7960a17 100644 --- a/docs/3.1.x/project_organization/index.html +++ b/docs/3.1.x/project_organization/index.html @@ -3,14 +3,14 @@ -Project Organization | Honeycomb - - +Project Organization | Honeycomb + +
-
Version: 3.1.x

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code.

Almost all of the changes needed for custom JsPsych tasks will be done in the src/ folder.

assets/

This folder contains any static files that are used by the app. Honeycomb starts with a few images used as icons for the installed applications.

build/

The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds. build/ should be left alone!

caution

The build folder is in Honeycomb's .gitignore and as such should never be added to git

emulator_data/

This folder contains starter data for the Firebase Emulators to use while developing locally. See the Firebase Scripts to use the data - emulator_data/ should be left alone!

env/

This folder contains different .env files used to pass environment variables (secrets and/or settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

node_modules/

danger

node_modules/ is written to when running npm install and should never be manually edited.

psiturkit/

The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see Deploy Online for more information. psiturkit/ should be left alone!

public/

The public directory contains files that are used as assets in the built app.

  • favicon.ico is the small icon you can see in the browser tab.
  • index.html is the entry point of the website
    • Changing <title>Honeycomb</title> will update the name you can see in the browser tab.
  • electron.js contains all of the code related to the electron app.

lib/

The lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes. version.json keeps track of the current git commit, which Honeycomb uses to keep track of the version of your task used for a given experiment.

src/

This folder contains the source code for the Honeycomb application.

__tests__/

Automated test cases should be created in this folder.

assets/

Any assets used by your task should be stored here, such as images and videos.

note

These assets are not statically generated like the root assets/ folder. Only assets needed by your task should go here.

components/

The React components that make up Honeycomb are located here.

  • App.jsx initializes and maintains the state of the application. It is also where communication is set up between the electron and psiturk processes.
  • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
  • JsPsychExperiment.jsx initializes the JsPsych experiment
  • Login.jsx handles user authentication based on the environment variables passed to Honeycomb

config/

Each file in the config directory contains settings for a different part of the task.

  • main.js contains the global settings (e.g. whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate language file.
  • trigger.js for equipment-related settings (e.g. event markers). It uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) and mturk-specific language. Common phrases can be written once in a language file and re-used throughout the task.

lib/

The utility functions and markup used in the tasks are located here. This allows for functions and html to be re-used wherever needed.

markup files contain HTML templates used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

tip

Be sure to look through utils.js for functions you might be able to use in your task

timelines/

A timeline is a collection of trials that JsPsych displays in the given order. Timelines can contain timelines themselves; you may want to break this nesting into multiple files in this folder.

main.js contains the root timeline which App.jsx loads into the <JsPsychExperiment> component.

trials/

A trial is the base unit of a JsPsych experiment. Each trial should be its own file within this folder - the files in src/timelines/ will combine these trials into the full experiment.

firebase.js

firebase.js contains all of the logic for creating, reading, and updating data in Firebase. You should not have to update this file.

index.css

index.css contains all of the styling in the application. Classes can be defined here and referenced in your markup.

index.js

index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:

<div id="root"></div>

Other Files

  • .github/workflows/ contains .yaml files used to build Honeycomb on a pull request (build.yaml) and create task executables either in a single instance (package.yaml) or for a full release (release.yaml)

  • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.

  • download-response-data.js is the script used to download data stored in Firestore to your local machine.

  • version.js is the script used to keep track of which version of the task a given experiment is using

danger

package-lock.json is written to when running npm install and should never be manually edited.

Git Files

  • .gitignore lists the folders and files that should be excluded from Git. Make sure all of your secrets and tokens are listed here!

Eslint Files

  • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.
  • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

Prettier Files

.prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.

Firebase Files

  • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
  • firebase.json contains the Firebase settings for Honeycomb. It should be left alone!
  • firestore.indexes.json contains the Firestore index settings for Honeycomb. It should be left alone!
  • firestore.rules contains the Firestore rules for creating/editing data. It should be left alone!
- - +
Version: 3.1.x

Project Organization

This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code.

Almost all of the changes needed for custom JsPsych tasks will be done in the src/ folder.

assets/

This folder contains any static files that are used by the app. Honeycomb starts with a few images used as icons for the installed applications.

build/

The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds. build/ should be left alone!

caution

The build folder is in Honeycomb's .gitignore and as such should never be added to git

emulator_data/

This folder contains starter data for the Firebase Emulators to use while developing locally. See the Firebase Scripts to use the data - emulator_data/ should be left alone!

env/

This folder contains different .env files used to pass environment variables (secrets and/or settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

node_modules/

danger

node_modules/ is written to when running npm install and should never be manually edited.

psiturkit/

The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see Deploy Online for more information. psiturkit/ should be left alone!

public/

The public directory contains files that are used as assets in the built app.

  • favicon.ico is the small icon you can see in the browser tab.
  • index.html is the entry point of the website
    • Changing <title>Honeycomb</title> will update the name you can see in the browser tab.
  • electron.js contains all of the code related to the electron app.

lib/

The lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags

config/

The config directory contains the config files needed for the electron app. This includes the event-marker details and event codes. version.json keeps track of the current git commit, which Honeycomb uses to keep track of the version of your task used for a given experiment.

src/

This folder contains the source code for the Honeycomb application.

__tests__/

Automated test cases should be created in this folder.

assets/

Any assets used by your task should be stored here, such as images and videos.

note

These assets are not statically generated like the root assets/ folder. Only assets needed by your task should go here.

components/

The React components that make up Honeycomb are located here.

  • App.jsx initializes and maintains the state of the application. It is also where communication is set up between the electron and psiturk processes.
  • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
  • JsPsychExperiment.jsx initializes the JsPsych experiment
  • Login.jsx handles user authentication based on the environment variables passed to Honeycomb

config/

Each file in the config directory contains settings for a different part of the task.

  • main.js contains the global settings (e.g. whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate language file.
  • trigger.js for equipment-related settings (e.g. event markers). It uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.

Other config files can be used to add settings for specific blocks or sub-sections of the experiment.

language/

Any language that is displayed in the experiment should be stored in this folder. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) and mturk-specific language. Common phrases can be written once in a language file and re-used throughout the task.

lib/

The utility functions and markup used in the tasks are located here. This allows for functions and html to be re-used wherever needed.

markup files contain HTML templates used throughout the task. Typically this will be a function that takes in some parameters and then returns a string with html.

tip

Be sure to look through utils.js for functions you might be able to use in your task

timelines/

A timeline is a collection of trials that JsPsych displays in the given order. Timelines can contain timelines themselves; you may want to break this nesting into multiple files in this folder.

main.js contains the root timeline which App.jsx loads into the <JsPsychExperiment> component.

trials/

A trial is the base unit of a JsPsych experiment. Each trial should be its own file within this folder - the files in src/timelines/ will combine these trials into the full experiment.

firebase.js

firebase.js contains all of the logic for creating, reading, and updating data in Firebase. You should not have to update this file.

index.css

index.css contains all of the styling in the application. Classes can be defined here and referenced in your markup.

index.js

index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:

<div id="root"></div>

Other Files

  • .github/workflows/ contains .yaml files used to build Honeycomb on a pull request (build.yaml) and create task executables either in a single instance (package.yaml) or for a full release (release.yaml)

  • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.

  • download-response-data.js is the script used to download data stored in Firestore to your local machine.

  • version.js is the script used to keep track of which version of the task a given experiment is using

danger

package-lock.json is written to when running npm install and should never be manually edited.

Git Files

  • .gitignore lists the folders and files that should be excluded from Git. Make sure all of your secrets and tokens are listed here!

Eslint Files

  • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.
  • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

Prettier Files

.prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.

Firebase Files

  • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
  • firebase.json contains the Firebase settings for Honeycomb. It should be left alone!
  • firestore.indexes.json contains the Firestore index settings for Honeycomb. It should be left alone!
  • firestore.rules contains the Firestore rules for creating/editing data. It should be left alone!
+ + \ No newline at end of file diff --git a/docs/3.1.x/quick_start/index.html b/docs/3.1.x/quick_start/index.html index 96c78304..c2196829 100644 --- a/docs/3.1.x/quick_start/index.html +++ b/docs/3.1.x/quick_start/index.html @@ -3,16 +3,16 @@ -Quick Start | Honeycomb - - +Quick Start | Honeycomb + +
-
Version: 3.1.x

Quick Start

Creating Your Task Repository

The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

  1. Go to the Honeycomb repository

  2. Click on Use this template and select Create a new repository. +

    Version: 3.1.x

    Quick Start

    Creating Your Task Repository

    The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

    1. Go to the Honeycomb repository

    2. Click on Use this template and select Create a new repository. Use this template

    3. Enter the owner, name, and description of your repository and click on Create repository from template. -Create repository

      note

      We recommend creating a public repository and leaving Include all branches unchecked

    4. Ensure the repositories workflow permissions are set to "Read and write permissions"

      Settings -> Actions -> General -> Workflow permissions

      GitHub workflow permissions settings

    Additional details about template repositories can be found on the Github Docs.

    Cloning the Repository

    With the repository now setup it can be cloned onto your computer.

    1. Navigate to the repository on GitHub.

    2. Click the Code button and copy the URL

      GitHub clone repo button
    3. Open a terminal and navigate to where you want the cloned directory

    Terminal.app
    cd 'path/to/directory'
    1. Clone the repo with the following command
    Paste the URL you copied earlier
     git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
    note

    Git can be downloaded here if it is not already on your system.

    Additional details and alternative methods for cloning a repository can be found on the Github Docs.

    Installing Prerequisites

    All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

    See Prerequisites for more information about these programs.

    Initial Install

    The most commonly used package manager on macOS is Homebrew.

    1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

      /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'
    2. Paste the following command and follow the prompts to install the listed programs:

      brew bundle
    3. Install Xcode (not available on Homebrew)

      xcode-select --install
    note

    If you are running into issues after installing the packages please restart your terminal and/or reboot your computer. This should resolve most issues.

    Setting Up Node

    NVM (Node Version Manager) is a tool for installing and using multiple versions on node on your computer. It must first be installed:

    1. Install NVM

      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
    2. Copy the version number listed in .nvmrc. The version may be different than the screenshot below.

      .nvmrc file
    3. Install that version.

      nvm install [version]
    4. Use the needed version. This will automatically check the version listed in the .nvmrc file.

      nvm use
    5. Set the current version as your default

      nvm alias default node
    note

    You can skip step 4 if you've already set a default node version in a different project.

    Install Dependencies

    There are many node packages used by Honeycomb that also need to be installed. Node (installed in the previous step) comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

    Install Honeycomb's dependencies
    npm install

    Certain dependencies are best installed globally within node. These tools will be available from the command line anywhere on your system.

    Install Honeycomb's global dependencies
    npm install -g electron firebase-tools dotenv-cli

    Run the Task in Development Mode

    Running the task in development mode causes it to hot-reload whenever changes are made to the app. This is how you'll run the project while building your task.

    Run the task in dev mode
    npm run dev

    This script launches an electron window with the task and inspector open.

    You can quit the task in the middle of development if needed:

    + Q

    Saving data

    Data is saved throughout the task, even when running in development mode. The location of the task is logged at the beginning of the task wherever you ran npm run dev.

    Note how the data is organized by study and participant. Every run through of the task will save the data somewhere within this folder!

    Edit the Task

    Now that the task is up and running we can make our first changes to the code! We'll edit the package.json file to reflect your information.

    1. Create a new branch

      git checkout -b <branch-name>
    2. Open package.json and edit it to reflect your app:

      1. name is your task's name, generally this is the name of our repository
      2. description should be rewritten to better match your task
      3. author is your lab (or PIs) name, email, and website
      4. version should be reset to 1.0.0
      5. repository is the link the GitHub repository you created earlier.
    3. Save your changes and commit them to git:

      git commit -m "Commit message goes here!"
    4. Create a pull request to bring your changes into the main branch

    Next Steps

    Honeycomb tasks can be configured to run as a web app in Firebase, or as desktop application via electron. The desktop application can receive port signals from EEG, cameras, foot pedals, and more.

    The Firebase page explains how to set up your task with Firebase.

    To learn more about how to configure your task for these different scenarios, see Environment Variables.

    The NPM Scripts page lists every script you can run and which environment they use.

- - +Create repository

note

We recommend creating a public repository and leaving Include all branches unchecked

  • Ensure the repositories workflow permissions are set to "Read and write permissions"

    Settings -> Actions -> General -> Workflow permissions

    GitHub workflow permissions settings
  • Additional details about template repositories can be found on the Github Docs.

    Cloning the Repository

    With the repository now setup it can be cloned onto your computer.

    1. Navigate to the repository on GitHub.

    2. Click the Code button and copy the URL

      GitHub clone repo button
    3. Open a terminal and navigate to where you want the cloned directory

    Terminal.app
    cd 'path/to/directory'
    1. Clone the repo with the following command
    Paste the URL you copied earlier
     git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
    note

    Git can be downloaded here if it is not already on your system.

    Additional details and alternative methods for cloning a repository can be found on the Github Docs.

    Installing Prerequisites

    All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

    See Prerequisites for more information about these programs.

    Initial Install

    The most commonly used package manager on macOS is Homebrew.

    1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

      /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'
    2. Paste the following command and follow the prompts to install the listed programs:

      brew bundle
    3. Install Xcode (not available on Homebrew)

      xcode-select --install
    note

    If you are running into issues after installing the packages please restart your terminal and/or reboot your computer. This should resolve most issues.

    Setting Up Node

    NVM (Node Version Manager) is a tool for installing and using multiple versions on node on your computer. It must first be installed:

    1. Install NVM

      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
    2. Copy the version number listed in .nvmrc. The version may be different than the screenshot below.

      .nvmrc file
    3. Install that version.

      nvm install [version]
    4. Use the needed version. This will automatically check the version listed in the .nvmrc file.

      nvm use
    5. Set the current version as your default

      nvm alias default node
    note

    You can skip step 4 if you've already set a default node version in a different project.

    Install Dependencies

    There are many node packages used by Honeycomb that also need to be installed. Node (installed in the previous step) comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

    Install Honeycomb's dependencies
    npm install

    Certain dependencies are best installed globally within node. These tools will be available from the command line anywhere on your system.

    Install Honeycomb's global dependencies
    npm install -g electron firebase-tools dotenv-cli

    Run the Task in Development Mode

    Running the task in development mode causes it to hot-reload whenever changes are made to the app. This is how you'll run the project while building your task.

    Run the task in dev mode
    npm run dev

    This script launches an electron window with the task and inspector open.

    You can quit the task in the middle of development if needed:

    + Q

    Saving data

    Data is saved throughout the task, even when running in development mode. The location of the task is logged at the beginning of the task wherever you ran npm run dev.

    Note how the data is organized by study and participant. Every run through of the task will save the data somewhere within this folder!

    Edit the Task

    Now that the task is up and running we can make our first changes to the code! We'll edit the package.json file to reflect your information.

    1. Create a new branch

      git checkout -b <branch-name>
    2. Open package.json and edit it to reflect your app:

      1. name is your task's name, generally this is the name of our repository
      2. description should be rewritten to better match your task
      3. author is your lab (or PIs) name, email, and website
      4. version should be reset to 1.0.0
      5. repository is the link the GitHub repository you created earlier.
    3. Save your changes and commit them to git:

      git commit -m "Commit message goes here!"
    4. Create a pull request to bring your changes into the main branch

    Next Steps

    Honeycomb tasks can be configured to run as a web app in Firebase, or as desktop application via electron. The desktop application can receive port signals from EEG, cameras, foot pedals, and more.

    The Firebase page explains how to set up your task with Firebase.

    To learn more about how to configure your task for these different scenarios, see Environment Variables.

    The NPM Scripts page lists every script you can run and which environment they use.

    + + \ No newline at end of file diff --git a/docs/3.1.x/troubleshooting/index.html b/docs/3.1.x/troubleshooting/index.html index 2bce379f..5f756ee3 100644 --- a/docs/3.1.x/troubleshooting/index.html +++ b/docs/3.1.x/troubleshooting/index.html @@ -3,14 +3,14 @@ -Troubleshooting | Honeycomb - - +Troubleshooting | Honeycomb + +
    -
    Version: 3.1.x

    Troubleshooting

    Inspecting Errors

    When developing Electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The React app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

    In case you want to find out where the error is coming from when running the app locally:

    • Try reviewing logs in the terminal
    • Inspect element in your browser by opening your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.

    Testing in Linux

    When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runner creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

    This is a "known issue" with some test runners on Linux, as in discussions here and here.

    One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

    • Command that initially fails with ENOSPC: npm test
    • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
    • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
    • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
    • Save, exit, and reload the config file: sudo sysctl -p
    • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
    • Retry the initial command, which should now succeed: npm test

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild. This should fix most issues.

    - - +
    Version: 3.1.x

    Troubleshooting

    Inspecting Errors

    When developing Electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The React app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

    In case you want to find out where the error is coming from when running the app locally:

    • Try reviewing logs in the terminal
    • Inspect element in your browser by opening your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.

    Testing in Linux

    When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runner creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

    This is a "known issue" with some test runners on Linux, as in discussions here and here.

    One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

    • Command that initially fails with ENOSPC: npm test
    • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
    • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
    • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
    • Save, exit, and reload the config file: sudo sysctl -p
    • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
    • Retry the initial command, which should now succeed: npm test

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild. This should fix most issues.

    + + \ No newline at end of file diff --git a/docs/3.1.x/variants/index.html b/docs/3.1.x/variants/index.html index 6d278fec..77441c83 100644 --- a/docs/3.1.x/variants/index.html +++ b/docs/3.1.x/variants/index.html @@ -3,14 +3,14 @@ -Variants | Honeycomb - - +Variants | Honeycomb + +
    -
    Version: 3.1.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    - - +
    Version: 3.1.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    + + \ No newline at end of file diff --git a/docs/3.1.x/version_control/index.html b/docs/3.1.x/version_control/index.html index d092aefd..07ff44e0 100644 --- a/docs/3.1.x/version_control/index.html +++ b/docs/3.1.x/version_control/index.html @@ -3,14 +3,14 @@ -Version Control | Honeycomb - - +Version Control | Honeycomb + +
    -
    Version: 3.1.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branch

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    git pr

    git pr info

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes form the template repository. It is tedious but extremely import to not accidentally overwrite your task when resolving these conflicts

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main.
    • Perform tests and code reviews before merges into main, not afterwards.
    • Every branch starts from main, and targets main.
    • Commit messages reflect intent.

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Cheatsheet

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout <branch>checkout and create the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    Alternative options

    VS Code

    Most IDEs have some built in tools for working with Git and VS Code is no exception. Check out this overview of source control in VS Code!

    GitHub Desktop

    GitHub Desktop is a GUI application for working with git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    - - +
    Version: 3.1.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branch

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    git pr

    git pr info

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes form the template repository. It is tedious but extremely import to not accidentally overwrite your task when resolving these conflicts

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main.
    • Perform tests and code reviews before merges into main, not afterwards.
    • Every branch starts from main, and targets main.
    • Commit messages reflect intent.

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Cheatsheet

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout <branch>checkout and create the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    Alternative options

    VS Code

    Most IDEs have some built in tools for working with Git and VS Code is no exception. Check out this overview of source control in VS Code!

    GitHub Desktop

    GitHub Desktop is a GUI application for working with git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    + + \ No newline at end of file diff --git a/docs/3.2.x/ci_cd/index.html b/docs/3.2.x/ci_cd/index.html index fc42a40c..d9ec8334 100644 --- a/docs/3.2.x/ci_cd/index.html +++ b/docs/3.2.x/ci_cd/index.html @@ -3,14 +3,14 @@ -Continuous Integration / Deployment | Honeycomb - - +Continuous Integration / Deployment | Honeycomb + +
    -
    Version: 3.2.x

    Continuous Integration / Deployment

    Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs.

    What are Github Actions

    GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

    GitHub Actions are written as YML files inside the .github/workflows/ folder of your repository.

    Honeycomb's CI/CD Workflows

    Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:

    • Home: The app does not expect event code triggers and photodiode spots.
    • Clinic: The app expects event code triggers and photodiode spots.
    tip

    Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.

    • pull_request.yaml: Every time an Pull Request (PR) is opened the software is built and tests are run for all platforms with home and clinic settings. This workflow does not upload desktop installers.

    • release.yml: Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.

    • workflow-package.yaml: Create installers for any/all platforms for the home and/or clinic setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.

      note

      On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their official documentation.

    • workflow-delete-artifacts.yaml: On demand workflow for deleting artifacts form your GitHub repository. This can be useful when the package.yaml workflow is run multiple times and you want to delete the artifacts from previous runs.

    Firebase

    • firebase-hosting-merge.yaml: Deploys the web version of the application to Firebase when a PR is merged into the main branch.
    • firebase-hosting-pull-request.yaml: Creates a preview version of the application with Firebase when a PR is opened.
      danger

      While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.

    note

    If you are not planning on ever using Firebase these workflows may be safely deleted.

    - - +
    Version: 3.2.x

    Continuous Integration / Deployment

    Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs.

    What are Github Actions

    GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

    GitHub Actions are written as YML files inside the .github/workflows/ folder of your repository.

    Honeycomb's CI/CD Workflows

    Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:

    • Home: The app does not expect event code triggers and photodiode spots.
    • Clinic: The app expects event code triggers and photodiode spots.
    tip

    Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.

    • pull_request.yaml: Every time an Pull Request (PR) is opened the software is built and tests are run for all platforms with home and clinic settings. This workflow does not upload desktop installers.

    • release.yml: Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.

    • workflow-package.yaml: Create installers for any/all platforms for the home and/or clinic setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.

      note

      On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their official documentation.

    • workflow-delete-artifacts.yaml: On demand workflow for deleting artifacts form your GitHub repository. This can be useful when the package.yaml workflow is run multiple times and you want to delete the artifacts from previous runs.

    Firebase

    • firebase-hosting-merge.yaml: Deploys the web version of the application to Firebase when a PR is merged into the main branch.
    • firebase-hosting-pull-request.yaml: Creates a preview version of the application with Firebase when a PR is opened.
      danger

      While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.

    note

    If you are not planning on ever using Firebase these workflows may be safely deleted.

    + + \ No newline at end of file diff --git a/docs/3.2.x/directory_structure/index.html b/docs/3.2.x/directory_structure/index.html index 8930e93a..fbbb880f 100644 --- a/docs/3.2.x/directory_structure/index.html +++ b/docs/3.2.x/directory_structure/index.html @@ -3,14 +3,14 @@ -Directory Structure | Honeycomb - - +Directory Structure | Honeycomb + +
    -
    Version: 3.2.x

    Directory Structure

    This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code.

    assets/

    This folder contains any static files that are used by the app. Honeycomb starts with a few images used as icons for the installed applications.

    caution

    Assets that pertain to your specific task should be added to the public/assets/ folder, not here!

    build/

    The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds. build/ should be left alone!

    danger

    The build folder is in Honeycomb's .gitignore and should never be added to git

    emulator_data/

    This folder contains starter data for the Firebase Emulators to use while developing locally. See the Firebase Scripts to use the data.

    danger

    emulator_data/ is written to when running npm run firebase:emulators:save and should never be manually edited.

    env/

    This folder contains different files used to pass environment variables (settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

    node_modules/

    danger

    node_modules/ is written to when running npm install and should never be manually edited.

    psiturkit/

    The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see PsiTurk for more information.

    caution

    Nothing in this folder should ever need to be manually edited.

    public/

    The public directory contains files that are used as assets in the built app.

    • index.html is the entry point of the website
      • Changing <title>Honeycomb</title> will update the name you can see in the browser tab.
    • favicon.ico is the small icon you can see in the browser tab.
    • electron.js contains all of the code related to the electron app.

    assets/

    The public/assets/ directory contains all of the images and videos needed to run your task.

    lib/

    The public/lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags.

    danger

    These files are minified versions of dependencies and should never be manually edited.

    config/

    The public/config/ directory contains the config files needed for the electron app. This includes the event-marker details and event codes. version.json keeps track of the current git commit, which Honeycomb uses to keep track of the version of your task used for a given experiment.

    src/

    This folder contains the source code for the Honeycomb application.

    App/

    Files relating to the React application. This is the code that runs your JsPsych task and shouldn't need to be changed.

    components/

    The React components that make up Honeycomb are located here.

    • App.jsx initializes and maintains the state of the application. It is also where communication is set up between the electron and psiturk processes.
    • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
    • JsPsychExperiment.jsx initializes the JsPsych experiment
    • Login.jsx handles user authentication based on the environment variables passed to Honeycomb

    deployments/

    Custom code used by the various deployments such as Firebase.

    caution

    Changes to these files will change how Honeycomb handles data and should be done with great caution.

    config/

    Each file in the config directory contains settings for a different part of the task.

    • main.js contains the global settings (e.g. whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate language file.
    • trigger.js for equipment-related settings (e.g. event markers). It uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.
    • config.json contains the settings for your task. Usage of the config file allows for easy updating of task settings. Common settings can be written once in the config file and re-used throughout the task.
    • language.json contains the language used in your task. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) and mturk-specific language. Common phrases can be written once in a language file and re-used throughout the task.

    lib/

    A library of utility and markup are located here. This allows for functions and html to be re-used wherever needed.

    markup/

    src/lib/markup/ files contain HTML templates used throughout the task.

    • stimuli.js contains a baseStimulus function that wraps some markup in a container that takes up 100% of the height and width of the viewport
    • photodiode.js contains the markup for the photodiode box and spot. It is displayed in the bottom right corner of the scree.
    • tags.js contains functions for wrapping language in common html tags.
      • p('Hello World') will return <p>Hello World</p>. You should always wrap your language in a tag to ensure it is displayed correctly.
    tip

    The tag function inside tags.js can be used to wrap language in any html tag you need.

    utils.js

    utils.js contains utility functions that can be used across a variety of trials. Be sure to look for functions you might be able to use in your task!

    timelines/

    A timeline is a collection of trials that JsPsych displays in the given order. Timelines can contain timelines themselves; you may want to break this nesting into multiple files in this folder.

    • main.js contains the JsPsych options and root timeline which App.jsx uses to run the experiment.
    • honeycombBlock.js contains the timeline for the Honeycomb block - the "meat" the example reaction-time task. It uses the task settings from config.json.
    • honeycombTimeline.js contains the timeline for the entire Honeycomb task. This includes the block timeline from honeycombBlock.js, as well as individual trials such as the welcome screen, full screen trial, and instructions.
    • preamble.js contains a base timeline for showing the name and welcome screen of an experiment, as well as automatically entering fullscreen mode. It adds the photodiode instructions to the timeline if Honeycomb is using the photodiode.

    trials/

    A trial is the base unit of a JsPsych experiment. Each trial should be its own file within this folder - the files in src/timelines/ will combine these trials into the full experiment.

    • honeycombTrials.js contains the individual trials used in the Honeycomb task. These trials are imported into honeycombBlock.js and honeycombTimeline.js.
    • adjustVolume.js prompts the user to adjust the volume on their computer.
    • camera.js contains trials for beginning and ending a camera recording.
    • fullscreen.js contains trials for entering and exiting fullscreen mode.
    • holdUpMarker.js prompts the user to connect their event marker and hold it up to the camera.
    • quizTrial.js contains trials for a quiz/survey.
    • startCode.js emits a start code to a photodiode spot and audible beep

    index.js

    index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:

    <div id="root"></div>

    Other Folders/Files

    • .nvmrc determines which version of node that Honeycomb is designed to be run on
    • .github/workflows/ contains .yaml files used to build Honeycomb on a pull request (build.yaml) and create task executables either in a single instance (package.yaml) or for a full release (release.yaml)
    • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.
    • cli.mjs is the script used to download and delete data stored in Firestore.
    • version.js is the script used to keep track of which version of the task a given experiment is using
    danger

    package-lock.json is written to when running npm install and should never be manually edited.

    Firebase Files

    • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
    • firebase.json contains the Firebase settings for Honeycomb.
    • firestore.indexes.json contains the Firestore index settings for Honeycomb.
    • firestore.rules contains the Firestore rules for creating/editing data.
    caution

    firebase.json, firestore.indexes.json, and firestore.rules shouldn't need to be manually edited.

    Git Files

    • .gitignore lists the folders and files that should be excluded from Git.
    danger

    Any secrets and/or tokens must be added to .gitignore or they will be visible to anyone with access to the repository!

    Eslint Files

    • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.
    • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

    Prettier Files

    .prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.

    - - +
    Version: 3.2.x

    Directory Structure

    This project directory is organized to be very modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used and only the pieces of code needed for any given file should be imported. This keeps the code maintainable with clear lineage and purpose for each piece of code.

    assets/

    This folder contains any static files that are used by the app. Honeycomb starts with a few images used as icons for the installed applications.

    caution

    Assets that pertain to your specific task should be added to the public/assets/ folder, not here!

    build/

    The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds. build/ should be left alone!

    danger

    The build folder is in Honeycomb's .gitignore and should never be added to git

    emulator_data/

    This folder contains starter data for the Firebase Emulators to use while developing locally. See the Firebase Scripts to use the data.

    danger

    emulator_data/ is written to when running npm run firebase:emulators:save and should never be manually edited.

    env/

    This folder contains different files used to pass environment variables (settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

    node_modules/

    danger

    node_modules/ is written to when running npm install and should never be manually edited.

    psiturkit/

    The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see PsiTurk for more information.

    caution

    Nothing in this folder should ever need to be manually edited.

    public/

    The public directory contains files that are used as assets in the built app.

    • index.html is the entry point of the website
      • Changing <title>Honeycomb</title> will update the name you can see in the browser tab.
    • favicon.ico is the small icon you can see in the browser tab.
    • electron.js contains all of the code related to the electron app.

    assets/

    The public/assets/ directory contains all of the images and videos needed to run your task.

    lib/

    The public/lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags.

    danger

    These files are minified versions of dependencies and should never be manually edited.

    config/

    The public/config/ directory contains the config files needed for the electron app. This includes the event-marker details and event codes. version.json keeps track of the current git commit, which Honeycomb uses to keep track of the version of your task used for a given experiment.

    src/

    This folder contains the source code for the Honeycomb application.

    App/

    Files relating to the React application. This is the code that runs your JsPsych task and shouldn't need to be changed.

    components/

    The React components that make up Honeycomb are located here.

    • App.jsx initializes and maintains the state of the application. It is also where communication is set up between the electron and psiturk processes.
    • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
    • JsPsychExperiment.jsx initializes the JsPsych experiment
    • Login.jsx handles user authentication based on the environment variables passed to Honeycomb

    deployments/

    Custom code used by the various deployments such as Firebase.

    caution

    Changes to these files will change how Honeycomb handles data and should be done with great caution.

    config/

    Each file in the config directory contains settings for a different part of the task.

    • main.js contains the global settings (e.g. whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate language file.
    • trigger.js for equipment-related settings (e.g. event markers). It uses a slightly different style of javascript as it is imported both in the React app as well as the electron process.
    • config.json contains the settings for your task. Usage of the config file allows for easy updating of task settings. Common settings can be written once in the config file and re-used throughout the task.
    • language.json contains the language used in your task. Usage of language json files allows for easy internationalization of the task (e.g. english and spanish) and mturk-specific language. Common phrases can be written once in a language file and re-used throughout the task.

    lib/

    A library of utility and markup are located here. This allows for functions and html to be re-used wherever needed.

    markup/

    src/lib/markup/ files contain HTML templates used throughout the task.

    • stimuli.js contains a baseStimulus function that wraps some markup in a container that takes up 100% of the height and width of the viewport
    • photodiode.js contains the markup for the photodiode box and spot. It is displayed in the bottom right corner of the scree.
    • tags.js contains functions for wrapping language in common html tags.
      • p('Hello World') will return <p>Hello World</p>. You should always wrap your language in a tag to ensure it is displayed correctly.
    tip

    The tag function inside tags.js can be used to wrap language in any html tag you need.

    utils.js

    utils.js contains utility functions that can be used across a variety of trials. Be sure to look for functions you might be able to use in your task!

    timelines/

    A timeline is a collection of trials that JsPsych displays in the given order. Timelines can contain timelines themselves; you may want to break this nesting into multiple files in this folder.

    • main.js contains the JsPsych options and root timeline which App.jsx uses to run the experiment.
    • honeycombBlock.js contains the timeline for the Honeycomb block - the "meat" the example reaction-time task. It uses the task settings from config.json.
    • honeycombTimeline.js contains the timeline for the entire Honeycomb task. This includes the block timeline from honeycombBlock.js, as well as individual trials such as the welcome screen, full screen trial, and instructions.
    • preamble.js contains a base timeline for showing the name and welcome screen of an experiment, as well as automatically entering fullscreen mode. It adds the photodiode instructions to the timeline if Honeycomb is using the photodiode.

    trials/

    A trial is the base unit of a JsPsych experiment. Each trial should be its own file within this folder - the files in src/timelines/ will combine these trials into the full experiment.

    • honeycombTrials.js contains the individual trials used in the Honeycomb task. These trials are imported into honeycombBlock.js and honeycombTimeline.js.
    • adjustVolume.js prompts the user to adjust the volume on their computer.
    • camera.js contains trials for beginning and ending a camera recording.
    • fullscreen.js contains trials for entering and exiting fullscreen mode.
    • holdUpMarker.js prompts the user to connect their event marker and hold it up to the camera.
    • quizTrial.js contains trials for a quiz/survey.
    • startCode.js emits a start code to a photodiode spot and audible beep

    index.js

    index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:

    <div id="root"></div>

    Other Folders/Files

    • .nvmrc determines which version of node that Honeycomb is designed to be run on
    • .github/workflows/ contains .yaml files used to build Honeycomb on a pull request (build.yaml) and create task executables either in a single instance (package.yaml) or for a full release (release.yaml)
    • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.
    • cli.mjs is the script used to download and delete data stored in Firestore.
    • version.js is the script used to keep track of which version of the task a given experiment is using
    danger

    package-lock.json is written to when running npm install and should never be manually edited.

    Firebase Files

    • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
    • firebase.json contains the Firebase settings for Honeycomb.
    • firestore.indexes.json contains the Firestore index settings for Honeycomb.
    • firestore.rules contains the Firestore rules for creating/editing data.
    caution

    firebase.json, firestore.indexes.json, and firestore.rules shouldn't need to be manually edited.

    Git Files

    • .gitignore lists the folders and files that should be excluded from Git.
    danger

    Any secrets and/or tokens must be added to .gitignore or they will be visible to anyone with access to the repository!

    Eslint Files

    • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.
    • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

    Prettier Files

    .prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal settings.

    + + \ No newline at end of file diff --git a/docs/3.2.x/environment_variables/index.html b/docs/3.2.x/environment_variables/index.html index c0e53281..9d54b7fe 100644 --- a/docs/3.2.x/environment_variables/index.html +++ b/docs/3.2.x/environment_variables/index.html @@ -3,14 +3,14 @@ -Environment Variables | Honeycomb - - +Environment Variables | Honeycomb + +
    -
    Version: 3.2.x

    Environment Variables

    Honeycomb uses environment variables to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text.

    NameDesktop vs OnlineBuild vs Run-timeDefault ValueTypeDescription
    REACT_APP_FIREBASEonlinebuildFalsebooleanIf the task is saving its data on Firebase.
    REACT_APP_VIDEOdesktopbuildFalsebooleanIf the participant is being video recorded.
    REACT_APP_USE_EEGdesktopbuildFalsebooleanIf the EEG (Event Marker) is available and recording.
    REACT_APP_USE_PHOTODIODEdesktopbuildFalsebooleanIf the photodiode spot is in use.
    REACT_APP_USE_VOLUMEdesktop onlinebuildFalsebooleanIf the participant should be asked to adjust their volume. (e.g. the task is using sound)
    REACT_APP_STUDY_IDdesktop onlinerun""stringThe id of a study. User will enter this value in the login screen if not set.
    REACT_APP_PARTICIPANT_IDdesktop onlinerun""stringThe id of a participant. User will enter this value in the login screen if not set.
    EVENT_MARKER_PRODUCT_IDdesktoprun""stringThe product ID of the event marker. If not set, it will default to the productID set in public/config/trigger.js. If neither are set it will attempt to connect using the COM name.
    EVENT_MARKER_COM_NAMEdesktoprun"COM3"stringThe COM name of the event marker. If not set, it will use the comName set in public/config/trigger.js. Field is ignored if EVENT_MARKER_PRODUCT_ID is set.
    note

    Note that Honeycomb does use other environment variables (e.g. ELECTRON_START_URL) but they do not effect the task itself. They can be safely ignored.

    Understanding the Environment Variables

    Run-time

    The run badge indicates the variable is set/determined each time the executable is run. Run-time environment variables allow for quick changes when running the task. They are convenient since they don't require building a whole different executable.

    • Desktop deployments must set these environment variables at the system level.
    • Online deployments must use Firebase, and store the runtime environment variables in Firestore.

    Build-time

    The build badge indicates the variable is set during the build phase (npm run build) and cannot be changed at run-time. These variables are configured via .env files in the env folder.

    The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

    package.json
    "[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]"

    See NPM Scripts for more

    - - +
    Version: 3.2.x

    Environment Variables

    Honeycomb uses environment variables to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text.

    NameDesktop vs OnlineBuild vs Run-timeDefault ValueTypeDescription
    REACT_APP_FIREBASEonlinebuildFalsebooleanIf the task is saving its data on Firebase.
    REACT_APP_VIDEOdesktopbuildFalsebooleanIf the participant is being video recorded.
    REACT_APP_USE_EEGdesktopbuildFalsebooleanIf the EEG (Event Marker) is available and recording.
    REACT_APP_USE_PHOTODIODEdesktopbuildFalsebooleanIf the photodiode spot is in use.
    REACT_APP_USE_VOLUMEdesktop onlinebuildFalsebooleanIf the participant should be asked to adjust their volume. (e.g. the task is using sound)
    REACT_APP_STUDY_IDdesktop onlinerun""stringThe id of a study. User will enter this value in the login screen if not set.
    REACT_APP_PARTICIPANT_IDdesktop onlinerun""stringThe id of a participant. User will enter this value in the login screen if not set.
    EVENT_MARKER_PRODUCT_IDdesktoprun""stringThe product ID of the event marker. If not set, it will default to the productID set in public/config/trigger.js. If neither are set it will attempt to connect using the COM name.
    EVENT_MARKER_COM_NAMEdesktoprun"COM3"stringThe COM name of the event marker. If not set, it will use the comName set in public/config/trigger.js. Field is ignored if EVENT_MARKER_PRODUCT_ID is set.
    note

    Note that Honeycomb does use other environment variables (e.g. ELECTRON_START_URL) but they do not effect the task itself. They can be safely ignored.

    Understanding the Environment Variables

    Run-time

    The run badge indicates the variable is set/determined each time the executable is run. Run-time environment variables allow for quick changes when running the task. They are convenient since they don't require building a whole different executable.

    • Desktop deployments must set these environment variables at the system level.
    • Online deployments must use Firebase, and store the runtime environment variables in Firestore.

    Build-time

    The build badge indicates the variable is set during the build phase (npm run build) and cannot be changed at run-time. These variables are configured via .env files in the env folder.

    The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

    package.json
    "[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]"

    See NPM Scripts for more

    + + \ No newline at end of file diff --git a/docs/3.2.x/event_triggers/index.html b/docs/3.2.x/event_triggers/index.html index 35633fa2..35fba904 100644 --- a/docs/3.2.x/event_triggers/index.html +++ b/docs/3.2.x/event_triggers/index.html @@ -3,14 +3,14 @@ -Event Triggers | Honeycomb - - +Event Triggers | Honeycomb + +
    -
    Version: 3.2.x

    Event Triggers

    BrainVision Trigger Box setup

    Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

    COMNAME

    and set the COM port to the correct value (e.g., COM3).

    Open Source Event Trigger setup

    Details on how to make the open source event trigger and photodiode can be found here.

    Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

    Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

    Send event code triggers

    Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

    Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper eventCode (e.g. eventCode.Fixation) as input.

    Run the task with event triggers

    Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

    - - +
    Version: 3.2.x

    Event Triggers

    BrainVision Trigger Box setup

    Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

    COMNAME

    and set the COM port to the correct value (e.g., COM3).

    Open Source Event Trigger setup

    Details on how to make the open source event trigger and photodiode can be found here.

    Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

    Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

    Send event code triggers

    Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

    Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper eventCode (e.g. eventCode.Fixation) as input.

    Run the task with event triggers

    Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

    + + \ No newline at end of file diff --git a/docs/3.2.x/firebase/index.html b/docs/3.2.x/firebase/index.html index 6e609b50..74fd206f 100644 --- a/docs/3.2.x/firebase/index.html +++ b/docs/3.2.x/firebase/index.html @@ -3,14 +3,14 @@ -Firebase | Honeycomb - - +Firebase | Honeycomb + +
    -
    Version: 3.2.x

    Firebase

    Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

    Setting up Firebase

    info

    Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

    Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

    Adding Products

    First we'll configure Firebase Hosting and Cloud Firestore on your project.

    1. Log in to Firebase with your Google account on the Firebase console.

    2. Navigate to your project from the console

    3. Register a new web app to your project (Register your app)

      note

      We recommend giving your web app the same name as your task's repository

    4. Add Firestore Database to your project (Create a Cloud Firestore database)

      note

      Chose production mode for the starting mode and the default "Cloud Firestore Location"

    The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

    Installing the Command Line Interface

    The Firebase CLI is installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

    Install the Firebase CLI
    npm install -g firebase-tools
    Login to Firebase
    firebase login

    A "command not found" error usually indicates firebase-tools has not been installed correctly

    Connecting Your Firebase Project

    1. Change the default project name of your task in .firebaserc
    .firebaserc
    {
    "projects": {
    "default": "<your project name>"
    }
    }
    1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

      1. Return to your project on the Firebase console.

      2. Navigate to your project setting

        Firebase project settings
      3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

        Firebase web credentials

        env/.env.firebase
        REACT_APP_FIREBASE="true"
        REACT_APP_apiKey=
        REACT_APP_authDomain=
        REACT_APP_projectId=
        REACT_APP_storageBucket=
        REACT_APP_messagingSenderId=
        REACT_APP_appId=

        Additional variables may be present in the console, they do not need to be copied.

    2. Deploy the default Firestore security rules

    Deploy Firestore rules
    firebase deploy --only firestore:rules

    Your task is now connected to an initialized Firebase project!

    Registering Studies

    caution

    This step must be followed exactly. See Security Rules for more information.

    1. Navigate to your Firestore Database in the console.
    2. Click "Start collection"
    3. Enter registered_studies for the collection id and click "next"
    4. Enter the id of your study for the document id
    5. Add a field named registered_participants with the type "array"
    6. Add the id of each study participant as a string inside the array
    Create a study

    The study should like this when you're finished:

    Example study

    Additional studies must be created inside the registered_studies collection

    Developing With Firebase

    Two terminal windows must be used while developing for Firebase. See here for instructions on splitting terminals in VSCode.

    Run Honeycomb with Firebase Enabled
    npm run dev:firebase
    Start the Firebase Emulators
    npm run firebase:emulators:start

    Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. It may be viewed at http://localhost:4000/firestore.

    info

    Honeycomb populates the Firestore emulators with the study s1 and participant p1.

    Deploying on Firebase

    Firebase deployments are handled automatically following Continuous Integration Continuous Development (CI/CD) practices using GitHub Actions. Here we will connect create custom actions that are connected to the task's Firebase project.

    Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

    Initialize Firebase hosting via Github actions
    firebase init hosting:github
    1. The window should log you in automatically. If not, follow the prompts to log in with the same account you used in the console.
    2. <username>/<repository name> refers to the name of your repository in Github. Be sure it's typed correctly!
    3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
    4. Enter npm install && npm run build:firebase for the prompt "What script should be run before every deploy?"
    5. Enter y to overwrite the current workflow file
    6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
    7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
    8. Enter y to overwrite the current workflow file

    Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Ensure the correct run script is present in both files.

    Github actions created by firebase

    Managing Data

    Honeycomb ships with a CLI script for managing data in Firebase. A local service account must be created in order to use it.

    Setting up a Service Account

    Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

    1. Return to the project settings your project on the Firebase console.

      Firebase project settings
    2. Click on the "Service accounts" tab

    3. Near the bottom, click "Generate new Private key" and "Generate Key"

    4. Rename the key firebase-service-account.json and move it to the root directory of your task. Be sure the file looks grayed out and is not picked up by git!

    danger

    A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

    Using the CLI Script

    Script Usage
    npm run cli

    The CLI script will guide you through the steps needed to manage your data appropriately:

    1. Whether you wish to download or delete data

    2. Entering the ID of a given study

    3. Entering the ID of a given participant on that study

    4. Selecting the sessions to download/delete

      info
      SPACE selects a single session and A toggles every session
    note

    The download script will prompt you for where the data should be saved. It defaults to ., which is your current folder. The folder must exist before running the script.

    Further Reading

    The Firebase Documentation details its Emulator Suite in much greater detail.

    Security Rules

    Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

    Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

    firestore.rules
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /participant_responses/{studyID}/participants/{participantID} {
    allow create, read:
    if participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;
    // ...
    }
    }
    }

    Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

    Line 6 defines our rule - it must pass for Honeycomb to connect to the document. participantID must be found in an array called registered_participants inside of a document at /databases/{database}/documents/registered_studies/{studyID}.

    Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must manually make these changes from the Firestore console.

    danger

    Firestore rules must define every match pattern in your project. Attempting to connect anywhere other than /participant_responses/{studyID}/participants/{participantID} will be automatically denied even if you add other collections to your database. This is why firestore.rules contains additional nested rules - these should be left alone.

    - - +
    Version: 3.2.x

    Firebase

    Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

    Setting up Firebase

    info

    Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

    Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

    Adding Products

    First we'll configure Firebase Hosting and Cloud Firestore on your project.

    1. Log in to Firebase with your Google account on the Firebase console.

    2. Navigate to your project from the console

    3. Register a new web app to your project (Register your app)

      note

      We recommend giving your web app the same name as your task's repository

    4. Add Firestore Database to your project (Create a Cloud Firestore database)

      note

      Chose production mode for the starting mode and the default "Cloud Firestore Location"

    The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

    Installing the Command Line Interface

    The Firebase CLI is installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

    Install the Firebase CLI
    npm install -g firebase-tools
    Login to Firebase
    firebase login

    A "command not found" error usually indicates firebase-tools has not been installed correctly

    Connecting Your Firebase Project

    1. Change the default project name of your task in .firebaserc
    .firebaserc
    {
    "projects": {
    "default": "<your project name>"
    }
    }
    1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

      1. Return to your project on the Firebase console.

      2. Navigate to your project setting

        Firebase project settings
      3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

        Firebase web credentials

        env/.env.firebase
        REACT_APP_FIREBASE="true"
        REACT_APP_apiKey=
        REACT_APP_authDomain=
        REACT_APP_projectId=
        REACT_APP_storageBucket=
        REACT_APP_messagingSenderId=
        REACT_APP_appId=

        Additional variables may be present in the console, they do not need to be copied.

    2. Deploy the default Firestore security rules

    Deploy Firestore rules
    firebase deploy --only firestore:rules

    Your task is now connected to an initialized Firebase project!

    Registering Studies

    caution

    This step must be followed exactly. See Security Rules for more information.

    1. Navigate to your Firestore Database in the console.
    2. Click "Start collection"
    3. Enter registered_studies for the collection id and click "next"
    4. Enter the id of your study for the document id
    5. Add a field named registered_participants with the type "array"
    6. Add the id of each study participant as a string inside the array
    Create a study

    The study should like this when you're finished:

    Example study

    Additional studies must be created inside the registered_studies collection

    Developing With Firebase

    Two terminal windows must be used while developing for Firebase. See here for instructions on splitting terminals in VSCode.

    Run Honeycomb with Firebase Enabled
    npm run dev:firebase
    Start the Firebase Emulators
    npm run firebase:emulators:start

    Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. It may be viewed at http://localhost:4000/firestore.

    info

    Honeycomb populates the Firestore emulators with the study s1 and participant p1.

    Deploying on Firebase

    Firebase deployments are handled automatically following Continuous Integration Continuous Development (CI/CD) practices using GitHub Actions. Here we will connect create custom actions that are connected to the task's Firebase project.

    Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

    Initialize Firebase hosting via Github actions
    firebase init hosting:github
    1. The window should log you in automatically. If not, follow the prompts to log in with the same account you used in the console.
    2. <username>/<repository name> refers to the name of your repository in Github. Be sure it's typed correctly!
    3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
    4. Enter npm install && npm run build:firebase for the prompt "What script should be run before every deploy?"
    5. Enter y to overwrite the current workflow file
    6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
    7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
    8. Enter y to overwrite the current workflow file

    Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Ensure the correct run script is present in both files.

    Github actions created by firebase

    Managing Data

    Honeycomb ships with a CLI script for managing data in Firebase. A local service account must be created in order to use it.

    Setting up a Service Account

    Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

    1. Return to the project settings your project on the Firebase console.

      Firebase project settings
    2. Click on the "Service accounts" tab

    3. Near the bottom, click "Generate new Private key" and "Generate Key"

    4. Rename the key firebase-service-account.json and move it to the root directory of your task. Be sure the file looks grayed out and is not picked up by git!

    danger

    A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

    Using the CLI Script

    Script Usage
    npm run cli

    The CLI script will guide you through the steps needed to manage your data appropriately:

    1. Whether you wish to download or delete data

    2. Entering the ID of a given study

    3. Entering the ID of a given participant on that study

    4. Selecting the sessions to download/delete

      info
      SPACE selects a single session and A toggles every session
    note

    The download script will prompt you for where the data should be saved. It defaults to ., which is your current folder. The folder must exist before running the script.

    Further Reading

    The Firebase Documentation details its Emulator Suite in much greater detail.

    Security Rules

    Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

    Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

    firestore.rules
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /participant_responses/{studyID}/participants/{participantID} {
    allow create, read:
    if participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;
    // ...
    }
    }
    }

    Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

    Line 6 defines our rule - it must pass for Honeycomb to connect to the document. participantID must be found in an array called registered_participants inside of a document at /databases/{database}/documents/registered_studies/{studyID}.

    Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must manually make these changes from the Firestore console.

    danger

    Firestore rules must define every match pattern in your project. Attempting to connect anywhere other than /participant_responses/{studyID}/participants/{participantID} will be automatically denied even if you add other collections to your database. This is why firestore.rules contains additional nested rules - these should be left alone.

    + + \ No newline at end of file diff --git a/docs/3.2.x/gh_pages/index.html b/docs/3.2.x/gh_pages/index.html index 1a000ee2..5d0a10af 100644 --- a/docs/3.2.x/gh_pages/index.html +++ b/docs/3.2.x/gh_pages/index.html @@ -3,14 +3,14 @@ -GitHub Pages | Honeycomb - - +GitHub Pages | Honeycomb + +
    -
    Version: 3.2.x

    GitHub Pages

    The .github/workflows/release.yml workflow will automatically deploy your task to GitHub pages if you have it enabled for your repository. It uploads the built website to the gh-pages branch. You can then access your task at <github user>.github.io/<repository>.

    danger

    Session data is downloaded to the user's local machine upon completion of the experiment when using GH Pages. Because of this, GH Pages is not suitable for fully online experiments.

    Setup

    Please follow the GitHub documentation for setting up GH Pages on your repository and make sure the publishing source for your repository is configured for gh-pages branch.

    - - +
    Version: 3.2.x

    GitHub Pages

    The .github/workflows/release.yml workflow will automatically deploy your task to GitHub pages if you have it enabled for your repository. It uploads the built website to the gh-pages branch. You can then access your task at <github user>.github.io/<repository>.

    danger

    Session data is downloaded to the user's local machine upon completion of the experiment when using GH Pages. Because of this, GH Pages is not suitable for fully online experiments.

    Setup

    Please follow the GitHub documentation for setting up GH Pages on your repository and make sure the publishing source for your repository is configured for gh-pages branch.

    + + \ No newline at end of file diff --git a/docs/3.2.x/index.html b/docs/3.2.x/index.html index de4dd619..248efe62 100644 --- a/docs/3.2.x/index.html +++ b/docs/3.2.x/index.html @@ -3,14 +3,14 @@ -Introduction | Honeycomb - - +Introduction | Honeycomb + +
    -
    Version: 3.2.x

    Introduction

    Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

    Flexible deployment online and in the lab

    Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

    Easy-to-install executables

    Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

    Foundation in jsPsych

    jsPsych 7 tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

    Community Driven

    Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

    Cite this work

    If you use Honeycomb in your work, please cite

    Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

    - - +
    Version: 3.2.x

    Introduction

    Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that are ready for deployment to different settings (desktop, or online) and support electrophysiological recordings, without significant changes to the code base.

    Flexible deployment online and in the lab

    Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

    Easy-to-install executables

    Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

    Foundation in jsPsych

    jsPsych 7 tasks can be converted to the Honeycomb structure to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

    Community Driven

    Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

    Cite this work

    If you use Honeycomb in your work, please cite

    Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

    + + \ No newline at end of file diff --git a/docs/3.2.x/javascript/index.html b/docs/3.2.x/javascript/index.html index c9bc0127..837c9dfa 100644 --- a/docs/3.2.x/javascript/index.html +++ b/docs/3.2.x/javascript/index.html @@ -3,14 +3,14 @@ -JavaScript | Honeycomb - - +JavaScript | Honeycomb + +
    -
    Version: 3.2.x

    JavaScript

    Learning JavaScript

    The Mozilla Developer Network Web Docs is the gold standard for programming on the web. The JavaScript page is an excellent place for further reading about JavaScript.

    Interactive Tutorials

    Learn JavaScript is an excellent platform for beginning to learn the JavaScript programming language. It is full of interactive tutorials and small projects.

    - - +
    Version: 3.2.x

    JavaScript

    Learning JavaScript

    The Mozilla Developer Network Web Docs is the gold standard for programming on the web. The JavaScript page is an excellent place for further reading about JavaScript.

    Interactive Tutorials

    Learn JavaScript is an excellent platform for beginning to learn the JavaScript programming language. It is full of interactive tutorials and small projects.

    + + \ No newline at end of file diff --git a/docs/3.2.x/local_application/index.html b/docs/3.2.x/local_application/index.html index 91e05dfa..0777b64e 100644 --- a/docs/3.2.x/local_application/index.html +++ b/docs/3.2.x/local_application/index.html @@ -3,14 +3,14 @@ -Local Application | Honeycomb - - +Local Application | Honeycomb + +
    -
    Version: 3.2.x

    Local Application

    A major feature of Honeycomb is the ability to bundle JsPsych tasks into applications that can be run on any computer in a lab or clinic. Installers for these applications can be created for Windows, Mac, and Linux. The applications can be run without an internet connection, and do not require any additional software to be installed on the computer.

    Installers for these application can be created on demand and/or automatically when a new release is created. This is called "Continuous Deployment" - more information about Honeycomb's CI/CD workflow can be found here here.

    Creating a Release

    Follow the GitHub documentation for creating a release.

    The tag should be in the format vX.X.X where X.X.X is the version number of the release. For example, if the release is version 1.0.0, the tag should be v1.0.0.

    danger

    Your release must included a new tag for the CI/CD workflow to work.

    Running the task

    1. Navigate to the repository's "Releases" tab and select the tag you just created.
    2. Download the installer for your operating system.
    3. Double click the installer to run it. Follow the instructions to install the application.
    4. The application will automatically start after the first instillation.

    The executable does not require installation of any additional software!

    Working with Data

    Data is automatically saved to a nested folder structure on the Desktop. Each session will be saved as its own .json file nested under the id of the study and participant.

    - - +
    Version: 3.2.x

    Local Application

    A major feature of Honeycomb is the ability to bundle JsPsych tasks into applications that can be run on any computer in a lab or clinic. Installers for these applications can be created for Windows, Mac, and Linux. The applications can be run without an internet connection, and do not require any additional software to be installed on the computer.

    Installers for these application can be created on demand and/or automatically when a new release is created. This is called "Continuous Deployment" - more information about Honeycomb's CI/CD workflow can be found here here.

    Creating a Release

    Follow the GitHub documentation for creating a release.

    The tag should be in the format vX.X.X where X.X.X is the version number of the release. For example, if the release is version 1.0.0, the tag should be v1.0.0.

    danger

    Your release must included a new tag for the CI/CD workflow to work.

    Running the task

    1. Navigate to the repository's "Releases" tab and select the tag you just created.
    2. Download the installer for your operating system.
    3. Double click the installer to run it. Follow the instructions to install the application.
    4. The application will automatically start after the first instillation.

    The executable does not require installation of any additional software!

    Working with Data

    Data is automatically saved to a nested folder structure on the Desktop. Each session will be saved as its own .json file nested under the id of the study and participant.

    + + \ No newline at end of file diff --git a/docs/3.2.x/npm_scripts/index.html b/docs/3.2.x/npm_scripts/index.html index 5d76ef59..dbe06e48 100644 --- a/docs/3.2.x/npm_scripts/index.html +++ b/docs/3.2.x/npm_scripts/index.html @@ -3,14 +3,14 @@ -NPM Scripts | Honeycomb - - +NPM Scripts | Honeycomb + +
    -
    Version: 3.2.x

    NPM Scripts

    Custom scripts for common shell commands can be written in package.json and run the node package manager (NPM). All of the commands needed to develop, build, and deploy Honeycomb are written as scripts.

    Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

    Executing an NPM Script
    npm run <script>

    Start

    • start runs the app in development mode and does NOT open a browser. This makes working with electron easier as it creates its own browser for development.
    • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.
    • start:electron: Waits for the app to be running (from start) and then starts an electron process.

    Firebase

    • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/
    • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/
    • firebase:download runs the firebase-download-script.js script, saving certain data in Firebase to your local machine.

    Dev

    npm run dev runs the app in development mode on Electron. It executes start and start:electron concurrently.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run dev with different environment variables.

    • dev:home runs the app with equipment disabled
    • dev:home:video runs the app with equipment disabled and video enabled
    • dev:clinic runs the app with equipment enabled
    • dev:clinic:video runs the app with equipment enabled and video enabled
    • dev:turk-prolific runs the app with prolific and PsiTurk enabled

    Firebase

    Working with Firebase is slightly different as it is meant to be run on the browser. npm run dev:firebase executes start:browser with Firebase enabled, which will automatically launch the running app in your default browser. It can be found on other browsers by navigating to localhost:3000.

    dev:firebase must be run in conjunction with firebase:emulators:start to work properly. This runs the Firebase Emulators locally with some dummy data. The emulator data can be viewed at localhost:4000.

    caution

    npm run firebase:emulators:start must be run in a separate terminal window that stays during development.

    tip

    The dummy study is s1 and the dummy participant is p1.

    Build

    npm run build creates a production build of the app in the build/ folder.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run build with different environment variables.

    • build:home builds the app with equipment disabled
    • build:home:video builds the app with equipment disabled and video enabled
    • build:clinic builds the app with equipment enabled
    • build:clinic:video builds the app with equipment enabled and video enabled
    • build:firebase builds the app with Firebase enabled
    • build:turk-prolific builds the app with prolific and PsiTurk enabled

    Package

    npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

    • npm run package:windows
    • npm run package:linux
    • npm run package:mac
    info

    Packaging for windows on a non-windows machine requires mono and wine to be installed.

    Miscellaneous

    • commit runs commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
    • lint uses Eslint to find problems in the code.
    • format uses Prettier to style code in a consistent format.
    • test launches the test runner in the interactive watch mode. See running tests for more information.
    - - +
    Version: 3.2.x

    NPM Scripts

    Custom scripts for common shell commands can be written in package.json and run the node package manager (NPM). All of the commands needed to develop, build, and deploy Honeycomb are written as scripts.

    Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

    Executing an NPM Script
    npm run <script>

    Start

    • start runs the app in development mode and does NOT open a browser. This makes working with electron easier as it creates its own browser for development.
    • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.
    • start:electron: Waits for the app to be running (from start) and then starts an electron process.

    Firebase

    • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/
    • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/
    • firebase:download runs the firebase-download-script.js script, saving certain data in Firebase to your local machine.

    Dev

    npm run dev runs the app in development mode on Electron. It executes start and start:electron concurrently.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run dev with different environment variables.

    • dev:home runs the app with equipment disabled
    • dev:home:video runs the app with equipment disabled and video enabled
    • dev:clinic runs the app with equipment enabled
    • dev:clinic:video runs the app with equipment enabled and video enabled
    • dev:turk-prolific runs the app with prolific and PsiTurk enabled

    Firebase

    Working with Firebase is slightly different as it is meant to be run on the browser. npm run dev:firebase executes start:browser with Firebase enabled, which will automatically launch the running app in your default browser. It can be found on other browsers by navigating to localhost:3000.

    dev:firebase must be run in conjunction with firebase:emulators:start to work properly. This runs the Firebase Emulators locally with some dummy data. The emulator data can be viewed at localhost:4000.

    caution

    npm run firebase:emulators:start must be run in a separate terminal window that stays during development.

    tip

    The dummy study is s1 and the dummy participant is p1.

    Build

    npm run build creates a production build of the app in the build/ folder.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run build with different environment variables.

    • build:home builds the app with equipment disabled
    • build:home:video builds the app with equipment disabled and video enabled
    • build:clinic builds the app with equipment enabled
    • build:clinic:video builds the app with equipment enabled and video enabled
    • build:firebase builds the app with Firebase enabled
    • build:turk-prolific builds the app with prolific and PsiTurk enabled

    Package

    npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

    • npm run package:windows
    • npm run package:linux
    • npm run package:mac
    info

    Packaging for windows on a non-windows machine requires mono and wine to be installed.

    Miscellaneous

    • commit runs commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
    • lint uses Eslint to find problems in the code.
    • format uses Prettier to style code in a consistent format.
    • test launches the test runner in the interactive watch mode. See running tests for more information.
    + + \ No newline at end of file diff --git a/docs/3.2.x/prerequisites/index.html b/docs/3.2.x/prerequisites/index.html index 7d1a6be9..eae5ad28 100644 --- a/docs/3.2.x/prerequisites/index.html +++ b/docs/3.2.x/prerequisites/index.html @@ -3,14 +3,14 @@ -Prerequisites | Honeycomb - - +Prerequisites | Honeycomb + +
    -
    Version: 3.2.x

    Prerequisites

    It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install, this page details what programs and packages are needed to run and build Honeycomb. There are some OS specific prerequisites needed to build a task as a desktop application.

    OS Independent

    Git

    git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

    GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

    Node Version Manager

    NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

    Python

    Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

    note

    Honeycomb needs version 3.7 or later to run - the installers use version 3.11.

    Oracle JDk

    Java is another high-level programming languages that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

    note

    Honeycomb needs version 11 or later to run - the installers use version 18.

    Visual Studio Code

    Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

    Mac-specific Installs

    X-Code

    XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

    Installing XCode
      xcode-select --install

    Rosetta

    Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple silicon system.

    Windows-specific Install

    Visual Studio

    Visual Studio is a special IDE for the Windows platform. It comes with everything needed to compile desktop applications from a PC. Visual Studio Community is a free to use platform.

    caution

    The "Desktop development with C++" workload must also be installed with Visual Studio. The automated installers should preselect this but you should double check to be certain!

    Manual Installation (macOS)

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Manual Installation (Windows)

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Manual Installation (Linux)

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

    Further Help

    If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

    - - +
    Version: 3.2.x

    Prerequisites

    It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install, this page details what programs and packages are needed to run and build Honeycomb. There are some OS specific prerequisites needed to build a task as a desktop application.

    OS Independent

    Git

    git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

    GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

    Node Version Manager

    NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

    Python

    Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

    note

    Honeycomb needs version 3.7 or later to run - the installers use version 3.11.

    Oracle JDk

    Java is another high-level programming languages that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

    note

    Honeycomb needs version 11 or later to run - the installers use version 18.

    Visual Studio Code

    Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

    Mac-specific Installs

    X-Code

    XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

    Installing XCode
      xcode-select --install

    Rosetta

    Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple silicon system.

    Windows-specific Install

    Visual Studio

    Visual Studio is a special IDE for the Windows platform. It comes with everything needed to compile desktop applications from a PC. Visual Studio Community is a free to use platform.

    caution

    The "Desktop development with C++" workload must also be installed with Visual Studio. The automated installers should preselect this but you should double check to be certain!

    Manual Installation (macOS)

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Manual Installation (Windows)

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Manual Installation (Linux)

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

    Further Help

    If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

    + + \ No newline at end of file diff --git a/docs/3.2.x/psiturk/index.html b/docs/3.2.x/psiturk/index.html index 06fb0c90..0a9df508 100644 --- a/docs/3.2.x/psiturk/index.html +++ b/docs/3.2.x/psiturk/index.html @@ -3,15 +3,15 @@ -PsiTurk | Honeycomb - - +PsiTurk | Honeycomb + +
    -
    Version: 3.2.x

    PsiTurk

    While honeycomb is optimized for use on a local application, we added functionality for usage with PsiTurk. The application will detect if it's being used in a Turk environment and will save the data to the default PsiTurk SQLite database.

    Prebuilt version

    When GitHub Actions is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts. The workflows responsible for building the PsiTurk application are .github/workflows/package.yml and .github/workflows/release.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

    If this is all you need, the build instructions below can be skipped!

    Build instructions

    To set up your PsiTurk project, we provide a script that does the conversion. -PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

    You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

    • Build the application: npm run build

    • Move to the psiturkit directory: cd psiturkit

    • If it's the first time you're running the script:

      ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>
    • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):

      ./psiturk-it -U -p <PATH_TO_NEW_PSITURK_PROJECT>

    Running PsiTurk

    After that, just navigate to your newly created PsiTurk project directory.

    shell> psiturk # start psiturk
    psiturk> server on # start server
    psiturk> debug # enter debug mode
    - - +
    Version: 3.2.x

    PsiTurk

    While honeycomb is optimized for use on a local application, we added functionality for usage with PsiTurk. The application will detect if it's being used in a Turk environment and will save the data to the default PsiTurk SQLite database.

    Prebuilt version

    When GitHub Actions is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts. The workflows responsible for building the PsiTurk application are .github/workflows/package.yml and .github/workflows/release.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

    If this is all you need, the build instructions below can be skipped!

    Build instructions

    To set up your PsiTurk project, we provide a script that does the conversion. +PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

    You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

    • Build the application: npm run build

    • Move to the psiturkit directory: cd psiturkit

    • If it's the first time you're running the script:

      ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>
    • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):

      ./psiturk-it -U -p <PATH_TO_NEW_PSITURK_PROJECT>

    Running PsiTurk

    After that, just navigate to your newly created PsiTurk project directory.

    shell> psiturk # start psiturk
    psiturk> server on # start server
    psiturk> debug # enter debug mode
    + + \ No newline at end of file diff --git a/docs/3.2.x/quick_start/index.html b/docs/3.2.x/quick_start/index.html index 15fb8794..ec1235a6 100644 --- a/docs/3.2.x/quick_start/index.html +++ b/docs/3.2.x/quick_start/index.html @@ -3,16 +3,16 @@ -Quick Start | Honeycomb - - +Quick Start | Honeycomb + +
    -
    Version: 3.2.x

    Quick Start

    Creating Your Task Repository

    The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

    1. Go to the Honeycomb repository

    2. Click on Use this template and select Create a new repository. +

      Version: 3.2.x

      Quick Start

      Creating Your Task Repository

      The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

      1. Go to the Honeycomb repository

      2. Click on Use this template and select Create a new repository. Use this template

      3. Enter the owner, name, and description of your repository and click on Create repository from template. -Create repository

        note

        We recommend creating a public repository and leaving Include all branches unchecked

      4. Ensure the repositories workflow permissions are set to "Read and write permissions"

        Settings -> Actions -> General -> Workflow permissions

        GitHub workflow permissions settings

      Additional details about template repositories can be found on the Github Docs.

      Cloning the Repository

      With the repository now setup it can be cloned onto your computer.

      1. Navigate to the repository on GitHub.

      2. Click the Code button and copy the URL

        GitHub clone repo button
      3. Open a terminal and navigate to where you want the cloned directory

      Terminal.app
      cd 'path/to/directory'
      1. Clone the repo with the following command
      Paste the URL you copied earlier
       git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
      note

      Git can be downloaded here if it is not already on your system.

      Additional details and alternative methods for cloning a repository can be found on the Github Docs.

      Installing Prerequisites

      All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

      See Prerequisites for more information about these programs.

      Initial Install

      The most commonly used package manager on macOS is Homebrew.

      1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

        /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'
      2. Paste the following command and follow the prompts to install the listed programs:

        brew bundle
      3. Install Xcode (not available on Homebrew)

        xcode-select --install
      note

      If you are running into issues after installing the packages please restart your terminal and/or reboot your computer. This should resolve most issues.

      Setting Up Node

      NVM (Node Version Manager) is a tool for installing and using multiple versions on node on your computer. It must first be installed:

      1. Install NVM

        curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
      2. Copy the version number listed in .nvmrc. The version may be different than the screenshot below.

        .nvmrc file
      3. Install that version.

        nvm install [version]
      4. Use the needed version. This will automatically check the version listed in the .nvmrc file.

        nvm use
      5. Set the current version as your default

        nvm alias default node
      note

      You can skip step 4 if you've already set a default node version in a different project.

      Install Dependencies

      There are many node packages used by Honeycomb that also need to be installed. Node (installed in the previous step) comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

      Install Honeycomb's dependencies
      npm install

      Certain dependencies are best installed globally within node. These tools will be available from the command line anywhere on your system.

      Install Honeycomb's global dependencies
      npm install -g electron firebase-tools dotenv-cli

      Run the Task in Development Mode

      Running the task in development mode causes it to hot-reload whenever changes are made to the app. This is how you'll run the project while building your task.

      Run the task in dev mode
      npm run dev

      This script launches an electron window with the task and inspector open.

      You can quit the task in the middle of development if needed:

      + Q

      Saving data

      Data is saved throughout the task, even when running in development mode. The location of the task is logged at the beginning of the task wherever you ran npm run dev.

      Note how the data is organized by study and participant. Every run through of the task will save the data somewhere within this folder!

      Edit the Task

      Now that the task is up and running we can make our first changes to the code! We'll edit the package.json file to reflect your information.

      1. Create a new branch

        git checkout -b <branch-name>
      2. Open package.json and edit it to reflect your app:

        1. name is your task's name, generally this is the name of our repository
        2. description should be rewritten to better match your task
        3. author is your lab (or PIs) name, email, and website
        4. honeycombVersion is the number currently in the version field
        5. version should be reset to 1.0.0
        6. repository is the link the GitHub repository you created earlier.
      3. Save your changes and commit them to git:

        git commit -m "Commit message goes here!"
      4. Create a pull request to bring your changes into the main branch

      Next Steps

      Honeycomb tasks can be configured to run as a web app in Firebase, or as desktop application via electron. The desktop application can receive port signals from EEG, cameras, foot pedals, and more.

      The Firebase page explains how to set up your task with Firebase.

      To learn more about how to configure your task for these different scenarios, see Environment Variables.

      The NPM Scripts page lists every script you can run and which environment they use.

    - - +Create repository

    note

    We recommend creating a public repository and leaving Include all branches unchecked

  • Ensure the repositories workflow permissions are set to "Read and write permissions"

    Settings -> Actions -> General -> Workflow permissions

    GitHub workflow permissions settings
  • Additional details about template repositories can be found on the Github Docs.

    Cloning the Repository

    With the repository now setup it can be cloned onto your computer.

    1. Navigate to the repository on GitHub.

    2. Click the Code button and copy the URL

      GitHub clone repo button
    3. Open a terminal and navigate to where you want the cloned directory

    Terminal.app
    cd 'path/to/directory'
    1. Clone the repo with the following command
    Paste the URL you copied earlier
     git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
    note

    Git can be downloaded here if it is not already on your system.

    Additional details and alternative methods for cloning a repository can be found on the Github Docs.

    Installing Prerequisites

    All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

    See Prerequisites for more information about these programs.

    Initial Install

    The most commonly used package manager on macOS is Homebrew.

    1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

      /bin/bash -c '$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)'
    2. Paste the following command and follow the prompts to install the listed programs:

      brew bundle
    3. Install Xcode (not available on Homebrew)

      xcode-select --install
    note

    If you are running into issues after installing the packages please restart your terminal and/or reboot your computer. This should resolve most issues.

    Setting Up Node

    NVM (Node Version Manager) is a tool for installing and using multiple versions on node on your computer. It must first be installed:

    1. Install NVM

      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
    2. Copy the version number listed in .nvmrc. The version may be different than the screenshot below.

      .nvmrc file
    3. Install that version.

      nvm install [version]
    4. Use the needed version. This will automatically check the version listed in the .nvmrc file.

      nvm use
    5. Set the current version as your default

      nvm alias default node
    note

    You can skip step 4 if you've already set a default node version in a different project.

    Install Dependencies

    There are many node packages used by Honeycomb that also need to be installed. Node (installed in the previous step) comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

    Install Honeycomb's dependencies
    npm install

    Certain dependencies are best installed globally within node. These tools will be available from the command line anywhere on your system.

    Install Honeycomb's global dependencies
    npm install -g electron firebase-tools dotenv-cli

    Run the Task in Development Mode

    Running the task in development mode causes it to hot-reload whenever changes are made to the app. This is how you'll run the project while building your task.

    Run the task in dev mode
    npm run dev

    This script launches an electron window with the task and inspector open.

    You can quit the task in the middle of development if needed:

    + Q

    Saving data

    Data is saved throughout the task, even when running in development mode. The location of the task is logged at the beginning of the task wherever you ran npm run dev.

    Note how the data is organized by study and participant. Every run through of the task will save the data somewhere within this folder!

    Edit the Task

    Now that the task is up and running we can make our first changes to the code! We'll edit the package.json file to reflect your information.

    1. Create a new branch

      git checkout -b <branch-name>
    2. Open package.json and edit it to reflect your app:

      1. name is your task's name, generally this is the name of our repository
      2. description should be rewritten to better match your task
      3. author is your lab (or PIs) name, email, and website
      4. honeycombVersion is the number currently in the version field
      5. version should be reset to 1.0.0
      6. repository is the link the GitHub repository you created earlier.
    3. Save your changes and commit them to git:

      git commit -m "Commit message goes here!"
    4. Create a pull request to bring your changes into the main branch

    Next Steps

    Honeycomb tasks can be configured to run as a web app in Firebase, or as desktop application via electron. The desktop application can receive port signals from EEG, cameras, foot pedals, and more.

    The Firebase page explains how to set up your task with Firebase.

    To learn more about how to configure your task for these different scenarios, see Environment Variables.

    The NPM Scripts page lists every script you can run and which environment they use.

    + + \ No newline at end of file diff --git a/docs/3.2.x/troubleshooting/index.html b/docs/3.2.x/troubleshooting/index.html index 0fbb4541..0ea96405 100644 --- a/docs/3.2.x/troubleshooting/index.html +++ b/docs/3.2.x/troubleshooting/index.html @@ -3,14 +3,14 @@ -Troubleshooting | Honeycomb - - +Troubleshooting | Honeycomb + +
    -
    Version: 3.2.x

    Troubleshooting

    Inspecting Errors

    When developing Electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The React app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

    In case you want to find out where the error is coming from when running the app locally:

    • Try reviewing logs in the terminal
    • Inspect element in your browser by opening your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.

    Testing in Linux

    When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runner creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

    This is a "known issue" with some test runners on Linux, as in discussions here and here.

    One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

    • Command that initially fails with ENOSPC: npm test
    • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
    • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
    • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
    • Save, exit, and reload the config file: sudo sysctl -p
    • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
    • Retry the initial command, which should now succeed: npm test

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild. This should fix most issues.

    - - +
    Version: 3.2.x

    Troubleshooting

    Inspecting Errors

    When developing Electron apps there are two processes: main, and renderer. In this case main corresponds to electron-starter.js and its console is wherever you called npm run dev or electron . from. renderer corresponds to the React App - this is everything else. The React app's console is in the electron/browser window and can be seen by using dev tools to inspect the window. When running npm run dev, it should open by default.

    In case you want to find out where the error is coming from when running the app locally:

    • Try reviewing logs in the terminal
    • Inspect element in your browser by opening your developer tools. For instance, in Chrome, this can be done via the menu View -> Developer or right-clicking and pressing inspect.

    Testing in Linux

    When running npm test on Linux, you might get an error that mentions ENOSPC. This is because the test runner creates "watchers" for files in the project repo in order to automatically re-run tests as the files change. Linux limits the number of watchers that can be created at a time and the default limit may be smaller than the number of files in the repo.

    This is a "known issue" with some test runners on Linux, as in discussions here and here.

    One simple workaround is to increase the number of allowed watchers (100000 seems to be sufficient):

    • Command that initially fails with ENOSPC: npm test
    • Check the configured limit on "watchers": cat /proc/sys/fs/inotify/max_user_watches
    • Edit the relevant Linux config file: sudo vim /etc/sysctl.conf
    • Add a line at the end of the config file: fs.inotify.max_user_watches=100000
    • Save, exit, and reload the config file: sudo sysctl -p
    • Check that the limit has changed: cat /proc/sys/fs/inotify/max_user_watches
    • Retry the initial command, which should now succeed: npm test

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Try deleting your node_modules folder and the package-lock.json then running npm install then npm run rebuild. This should fix most issues.

    + + \ No newline at end of file diff --git a/docs/3.2.x/variants/index.html b/docs/3.2.x/variants/index.html index c78516e7..2c1cd6ee 100644 --- a/docs/3.2.x/variants/index.html +++ b/docs/3.2.x/variants/index.html @@ -3,14 +3,14 @@ -Variants | Honeycomb - - +Variants | Honeycomb + +
    -
    Version: 3.2.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    - - +
    Version: 3.2.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    + + \ No newline at end of file diff --git a/docs/3.2.x/version_control/index.html b/docs/3.2.x/version_control/index.html index b2c8ac7a..ea2307e3 100644 --- a/docs/3.2.x/version_control/index.html +++ b/docs/3.2.x/version_control/index.html @@ -3,14 +3,14 @@ -Version Control | Honeycomb - - +Version Control | Honeycomb + +
    -
    Version: 3.2.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branch

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    git pr

    git pr info

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes form the template repository. It is tedious but extremely import to not accidentally overwrite your task when resolving these conflicts

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main.
    • Perform tests and code reviews before merges into main, not afterwards.
    • Every branch starts from main, and targets main.
    • Commit messages reflect intent.

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Cheatsheet

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout <branch>checkout and create the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    Alternative options

    VS Code

    Most IDEs have some built in tools for working with Git and VS Code is no exception. Check out this overview of source control in VS Code!

    GitHub Desktop

    GitHub Desktop is a GUI application for working with git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    - - +
    Version: 3.2.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, for the exception of few used purely to synchronize with a remote. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branch

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    git pr

    git pr info

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes form the template repository. It is tedious but extremely import to not accidentally overwrite your task when resolving these conflicts

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main.
    • Perform tests and code reviews before merges into main, not afterwards.
    • Every branch starts from main, and targets main.
    • Commit messages reflect intent.

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Cheatsheet

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout <branch>checkout and create the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    Alternative options

    VS Code

    Most IDEs have some built in tools for working with Git and VS Code is no exception. Check out this overview of source control in VS Code!

    GitHub Desktop

    GitHub Desktop is a GUI application for working with git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    + + \ No newline at end of file diff --git a/docs/3.3.x/ci_cd/index.html b/docs/3.3.x/ci_cd/index.html new file mode 100644 index 00000000..f97b7c21 --- /dev/null +++ b/docs/3.3.x/ci_cd/index.html @@ -0,0 +1,16 @@ + + + + + +Continuous Integration / Deployment | Honeycomb + + + + +
    +
    Version: 3.3.x

    Continuous Integration / Deployment

    Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs.

    What are Github Actions

    GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

    GitHub Actions are written as YML files inside the .github/workflows/ folder of your repository.

    Honeycomb's CI/CD Workflows

    Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:

    • Home: The app does not expect event code triggers and photodiode spots.
    • Clinic: The app expects event code triggers and photodiode spots.
    tip

    Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.

    • pull_request.yaml: Every time a Pull Request (PR) is created the software is built and tests are run for all platforms with home and clinic settings. This workflow does not upload desktop installers.

    • release.yml: Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.

    • workflow-package.yaml: Create installers for any/all platforms for the home and/or clinic setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.

      note

      On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their official documentation.

    • workflow-delete-artifacts.yaml: On-demand workflow for deleting artifacts form your GitHub repository. This can be useful when the package.yaml workflow is run multiple times and you want to delete the artifacts from previous runs.

    Firebase

    • firebase-hosting-merge.yaml: Deploys the web version of the application to Firebase when a PR is merged into the main branch.
    • firebase-hosting-pull-request.yaml: Creates a preview version of the application with Firebase when a PR is opened.
      danger

      While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.

    note

    These workflows may be safely deleted if you are not planning to ever use Firebase.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/directory_structure/index.html b/docs/3.3.x/directory_structure/index.html new file mode 100644 index 00000000..bac5684b --- /dev/null +++ b/docs/3.3.x/directory_structure/index.html @@ -0,0 +1,17 @@ + + + + + +Directory Structure | Honeycomb + + + + +
    +
    Version: 3.3.x

    Directory Structure

    This project directory is organized to be modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used, and only the pieces of code needed for any given file should be imported.

    assets/

    This folder contains static files that are used by the application. Honeycomb uses a few images as icons for the installed applications.

    caution

    Assets that pertain to your specific task should be added to the public/assets/ folder, not here!

    build/

    The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds.

    caution

    build/ should be left alone! It is in Honeycomb's .gitignore and should never be added to git.

    emulator_data/

    This folder contains starter data for the Firebase Emulators to use while developing locally. The Firebase Scripts detail how to use this data.

    caution

    emulator_data/ is written to when running npm run firebase:emulators:save and should never be edited.

    env/

    This folder contains different files used to pass environment variables (settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

    node_modules/

    caution

    node_modules/ is written to when running npm install and should never be edited. It is in Honeycomb's .gitignore and should never be added to git.

    psiturkit/

    The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see PsiTurk for more information.

    caution

    This folder involves a Honeycomb deployment. The files do not need to be edited.

    public/

    The public directory contains files that are used as assets in the built app.

    • index.html is the entry point of the website
      • Changing <title>Honeycomb</title> will update the text in the browser tab!
    • favicon.ico is the small (16x16px) icon you can see in the browser tab
    • manifest.json contains metadata about the web app
    caution

    manifest.json involves project metadata and does not need to be edited.

    assets/

    The public/assets/ directory contains all of the audio, images, and videos needed to run your task.

    electron/

    The public/electron/ directory contains the files needed to run Honeycomb as an Electron app.

    • main.js sets up Electron itself
    • preload.js sets up the communication between the main and renderer processes.
    caution

    This folder involves a Honeycomb deployment, the files do not need to be edited.

    lib/

    The public/lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags.

    caution

    This folder involves dependencies for a Honeycomb deployment, the files should not be edited.

    src/

    This folder contains the source code for the Honeycomb application.

    • index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:
      <div id="root"></div>
      caution

      index.js runs Honeycomb itself and should not be edited.

    App/

    Files relating to the React application.

    caution

    This folder holds the code that runs the jsPsych task, the files do not need to be edited.

    components/

    The React components that make up Honeycomb are located here.

    • App.jsx initializes and maintains the state of the application.
    • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
    • JsPsychExperiment.jsx initializes the jsPsych experiment.
    • Login.jsx handles user authentication based on the environment variables passed to Honeycomb.

    deployments/

    Custom code used by the various deployments such as Firebase.

    caution

    This folder involves Honeycomb deployments, the files do not need to be edited.

    config/

    Each file in the config directory contains settings for a different part of the task.

    • language.json contains the language used in your task. This file allows for easy internationalization of the task (e.g. English and Spanish) and mturk-specific language. Common phrases can be written once and re-used throughout the task.

    • main.js contains the global settings (e.g., whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate files.

    • settings.json contains the settings for your task. Usage of the config file allows for easy updating of task settings. Common settings can be written once and re-used throughout the task.

    • trigger.js contains equipment-related settings for a trigger box. The eventCodes are especially important for marking the types of given trials.

    experiment/

    tip

    This is where you'll spend most of your time while developing your task!

    • index.js contains the outermost logic for running the experiment. It loads experiment's styling and exports the main timeline and options for the experiment.
      caution

      The experiment will not run correctly if the names jsPsychOptions or buildTimeline are changed.

    • honeycomb.js contains the options and timeline for the jsPsych tutorial's "Simple React Time Task". It serves as an example for the experiment timeline for your task.
      tip

      This is just an example experiment! Be sure to write your experiment in its own file. +{/ TODO: Link to this in the quick_start guide once it's ready /}

    procedures/

    A procedure is a tested timeline of trials in jsPsych. Common parameters can be used across trials, and the trials within a procedure can be ordered and repeated as desired. Check out the JsPsych documentation for more information on creating a custom procedure.

    • startProcedure.js contains the procedure for the start of the experiment. It uses the environment and task settings from config.json to create a nested timeline that correctly starts the experiment.
    • honeycombProcedure.js contains the procedure for the Honeycomb task. It displays a fixation dot and presents the stimulus of the example task.
      tip

      This is just an example procedure! Be sure to write your procedures in their own files.

    • endProcedure.js contains the procedure for the end of the experiment. It uses the environment and task settings from config.json to create a nested timeline that correctly end the experiment.

    trials/

    A trial is the base unit of an experiment. These trials are ordered into procedures and timelines to create the task itself.

    • adjustVolume.js prompts the user to adjust the volume on their tablet.

    • camera.js contains trials for beginning and ending a camera recording.

    • conclusion.js displays a message to the user indicating that the experiment has concluded.

    • fixation.js displays a fixation dot in the center of the screen. It contains additional logic for flashing a photodiode spot and emitting an event code based on the environment settings.

    • fullscreen.js contains trials for entering and exiting fullscreen mode.

    • holdUpMarker.js prompts the user to connect their event marker and hold it up to the camera.

    • honeycombTrials.js contains the individual trials used in the Honeycomb task. These trials are imported into experiment/procedures/honeycombProcedure.js and experiment/honeycomb.js.

      tip

      These trials are for the example experiment! Be sure to write trials pertaining to your task in their own file(s).

    • introduction.js displays a message to the user welcoming them to the experiment. They must click on a button to continue.

    • name.js displays the name of the task to the user.

    • startCode.js emits a start code to a photodiode spot and audible beep.

    • survey.js contains trials pertaining to a survey/quiz for the user to complete.

    lib/

    A library of utility and markup functions are located here. This allows for functions and html to be re-used wherever needed.

    • utils.js contains utility functions that can be used across a variety of trials. Be sure to look for functions you might be able to use in your task!

    markup/

    Markup files contain HTML templates used throughout the task.

    • photodiode.js contains the markup for the photodiode box and spot displayed in the bottom right corner of the screen
    • tags.js contains functions for wrapping language in common html tags. You should always wrap your language in a tag to ensure it is displayed correctly.
      • For example: p('Hello World') will return <p>Hello World</p>.
    tip

    The tag function inside tags.js can be used to wrap language in any html tag you need.

    Other Folders/Files

    • .nvmrc determines which version of node that Honeycomb is designed to be run on.

    • .github/workflows/ contains .yaml files used for CI/CD with GitHub Actions.

    • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.

    • cli.mjs is the script used to download and delete data stored in Firestore.

    • version.js is the script used to keep track of which version of the task a given experiment is using.

    caution

    cli.mjs and version.js are automated scripts and should not be edited.

    package-lock.json is written to when running npm install and should never be edited.

    Firebase Files

    • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
    • firebase.json contains the Firebase settings for Honeycomb.
    • firestore.indexes.json contains the Firestore index settings for Honeycomb.
    • firestore.rules contains the Firestore rules for creating/editing data.
    caution

    firebase.json and firestore.indexes.json are default configs and shouldn't need to be edited.

    Git Files

    • .gitignore lists the folders and files that should be excluded from Git.
    caution

    Any secrets and/or tokens must be added to .gitignore or they will be visible to anyone with access to the repository!

    Eslint Files

    • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal preference.
    • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

    Prettier Files

    .prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal preference.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/environment_variables/index.html b/docs/3.3.x/environment_variables/index.html new file mode 100644 index 00000000..9160c3b1 --- /dev/null +++ b/docs/3.3.x/environment_variables/index.html @@ -0,0 +1,16 @@ + + + + + +Environment Variables | Honeycomb + + + + +
    +
    Version: 3.3.x

    Environment Variables

    Honeycomb uses environment variables to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text.

    NameDesktop vs OnlineBuild vs Run-timeDefault ValueTypeDescription
    REACT_APP_FIREBASEonlinebuildFalsebooleanIf the task is saving its data on Firebase.
    REACT_APP_VIDEOdesktopbuildFalsebooleanIf the participant is being video recorded.
    REACT_APP_USE_EEGdesktopbuildFalsebooleanIf the EEG (Event Marker) is available and recording.
    REACT_APP_USE_PHOTODIODEdesktopbuildFalsebooleanIf the photodiode spot is in use.
    REACT_APP_USE_VOLUMEdesktop onlinebuildFalsebooleanIf the participant should be asked to adjust their volume. (e.g. the task is using sound)
    REACT_APP_STUDY_IDdesktop onlinerun""stringThe id of a study. User will enter this value in the login screen if not set.
    REACT_APP_PARTICIPANT_IDdesktop onlinerun""stringThe id of a participant. User will enter this value in the login screen if not set.
    EVENT_MARKER_PRODUCT_IDdesktoprun""stringThe product ID of the event marker. If not set, it will default to the productID set in public/config/trigger.js. If neither are set, it will attempt to connect using the COM name.
    EVENT_MARKER_COM_NAMEdesktoprun"COM3"stringThe COM name of the event marker. If not set, it will use the comName set in public/config/trigger.js. Field is ignored if EVENT_MARKER_PRODUCT_ID is set.
    note

    Note that Honeycomb does use other environment variables (e.g., ELECTRON_START_URL) but they do not effect the task itself. They can be safely ignored.

    Understanding the Environment Variables

    Run-time

    The run badge indicates the variable is set/determined each time the executable is run. Run-time environment variables allow for quick changes when running the task. They are convenient since they don't require building a whole different executable.

    • Desktop deployments must set these environment variables at the system level.
    • Online deployments must use Firebase, and store the runtime environment variables in Firestore.

    Build-time

    The build badge indicates the variable is set during the build phase (npm run build) and cannot be changed at run-time. These variables are configured via .env files in the env folder.

    The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

    package.json
    "[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]"

    See NPM Scripts for more

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/event_triggers/index.html b/docs/3.3.x/event_triggers/index.html new file mode 100644 index 00000000..d7d5c8d0 --- /dev/null +++ b/docs/3.3.x/event_triggers/index.html @@ -0,0 +1,16 @@ + + + + + +Event Triggers | Honeycomb + + + + +
    +
    Version: 3.3.x

    Event Triggers

    BrainVision Trigger Box setup

    Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

    COMNAME

    and set the COM port to the correct value (e.g., COM3).

    Open Source Event Trigger setup

    Details on how to make the open source event trigger and photodiode can be found here.

    Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

    Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

    Send event code triggers

    Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

    Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper code (e.g. eventCode.Fixation) as input.

    Run the task with event triggers

    Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/firebase/index.html b/docs/3.3.x/firebase/index.html new file mode 100644 index 00000000..95914bc8 --- /dev/null +++ b/docs/3.3.x/firebase/index.html @@ -0,0 +1,16 @@ + + + + + +Firebase | Honeycomb + + + + +
    +
    Version: 3.3.x

    Firebase

    Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

    Setting up Firebase

    info

    Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

    Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

    Adding Products

    First we'll configure Firebase Hosting and Cloud Firestore on your project.

    1. Log in to Firebase with your Google account on the Firebase console

    2. Navigate to your project from the console

    3. Register a new web app to your project (Register your app)

      note

      We recommend giving your web app the same name as your task's repository

    4. Add Firestore Database to your project (Create a Cloud Firestore database)

      note

      Choose production mode for the starting mode and the default "Cloud Firestore Location"

    The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

    Installing the Command Line Interface

    The Firebase CLI is installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

    Login to Firebase
    firebase login

    A command not found error usually indicates firebase-tools has not been installed correctly. Re-running npm install -g firebase-tools should fix this issue.

    Connecting Your Firebase Project

    1. Change the default project name of your task in .firebaserc
    .firebaserc
    {
    "projects": {
    "default": "<your project name>"
    }
    }
    1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

      1. Return to your project on the Firebase console

      2. Navigate to your project setting

        Firebase project settings
      3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

        Firebase web credentials

        env/.env.firebase
        REACT_APP_FIREBASE="true"
        REACT_APP_apiKey=
        REACT_APP_authDomain=
        REACT_APP_projectId=
        REACT_APP_storageBucket=
        REACT_APP_messagingSenderId=
        REACT_APP_appId=

        Additional variables may be present in the console, they do not need to be copied.

    2. Deploy the default Firestore security rules

    Deploy Firestore rules
    firebase deploy --only firestore:rules

    Your task is now connected to an initialized Firebase project!

    Developing With Firebase

    Two terminal windows must be used while developing for Firebase. See here for instructions on splitting terminals in VSCode.

    Run Honeycomb with Firebase Enabled
    npm run dev:firebase
    Start the Firebase Emulators
    npm run firebase:emulators:start

    Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. It may be viewed on localhost:4000.

    info

    Honeycomb populates the Firestore emulators with the study s1 and participant p1.

    Deploying on Firebase

    Firebase deployments are handled automatically following Continuous Integration Continuous Development (CI/CD) practices using GitHub Actions. Here we will create custom actions that are connected to the task's Firebase project.

    Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

    Initialize Firebase hosting via Github actions
    firebase init hosting:github
    1. The window should log you in automatically; if not, follow the prompts to log in with the same account you used in the console
    2. <username>/<repository name> refers to the name of your repository in Github - be sure it's typed correctly!
    3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
    4. Enter npm install && npm run build:firebase for the prompt "What script should be run before every deploy?"
    5. Enter y to overwrite the current workflow file
    6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
    7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
    8. Enter y to overwrite the current workflow file

    Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Ensure the correct run script is present in both files.

    Github actions created by firebase

    Managing Data

    Honeycomb ships with a CLI script for managing data in Firebase. A local service account must be created in order to use it.

    Setting up a Service Account

    Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

    1. Return to the project settings your project on the Firebase console

      Firebase project settings
    2. Click on the "Service accounts" tab

    3. Near the bottom, click "Generate new Private key" and "Generate Key"

    4. Rename the key firebase-service-account.json and move it to the root directory of your task - be sure the file looks grayed out and is not picked up by git!

    danger

    A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

    Using the CLI Script

    Script Usage
    npm run cli

    The CLI script will guide you through the steps needed to manage your data appropriately:

    1. Whether you wish to download or delete data

    2. Entering the ID of a given study

    3. Entering the ID of a given participant on that study

    4. Selecting the sessions to download/delete

      info
      SPACE selects a single session and A toggles every session
    note

    The download script will prompt you for where the data should be saved. It defaults to ., which is your current folder. The folder must exist before running the script.

    Further Reading

    The Firebase Documentation details its Emulator Suite in much greater detail.

    Security Rules

    Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

    Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

    firestore.rules
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /participant_responses/{studyID}/participants/{participantID} {
    allow create, read:
    if
    // Allows any combination of studyID and participantID to be created in Firebase
    true
    // participantID must be in the registered_participants array in the registered_studies/{studyID} document
    // participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;

    // experimentID must be in the data subcollection
    match /data/{experimentID} {
    allow create, read: if true

    // trialID must be in the trials subcollection
    match /trials/{trialID} {
    allow create, read: if true
    }
    }
    }
    }
    }

    Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

    Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must use the CLI script to delete data.

    Lines 6 through 10 defines our rule for creating a document for a given participant at participant_responses/{studyID}/participants/{participantID}. Honeycomb ships with two possible rules:

    1. Line 8 specifies true which allows any combination of studyID and participantID to be created in Firebase.

      info

      This is the default rule Honeycomb ships with. It is recommended to leave this rule as is and handle the registration of studies in another tool such as Prolific.

    2. Line 10 only allows a participantID to be created if the value is in an array called registered_participants inside of a document at registered_studies/{studyID}. This ensures pre-registration of every study and participant - the next section explains how to register studies.

    caution

    Firestore rules define every valid path for data in your project. Attempting to connect anywhere besides the paths in your Firestore rules will be automatically denied, even if you have manually saved data elsewhere. This is why firestore.rules contains the nested rules in lines 12 - 20. These should be left alone.

    Registering Studies

    1. Navigate to your Firestore Database in the Firebase console

    2. Click "Start collection"

    3. Enter registered_studies as the collection ID

    4. Enter the id of your study as the document id

    5. Click "Add Field".

    6. Enter registered_participants as the field name, and set the type "array"

    7. Add the id of each study participant to the array as type "string"

      Create a study

    The study should look like this when you're finished:

    Example study

    Additional studies are created as documents inside the registered_studies collection

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/gh_pages/index.html b/docs/3.3.x/gh_pages/index.html new file mode 100644 index 00000000..2df6889e --- /dev/null +++ b/docs/3.3.x/gh_pages/index.html @@ -0,0 +1,16 @@ + + + + + +GitHub Pages | Honeycomb + + + + +
    +
    Version: 3.3.x

    GitHub Pages

    The .github/workflows/release.yml workflow will automatically deploy your task to GitHub pages if you have it enabled for your repository. It uploads the built website to the gh-pages branch. You can then access your task at <github user>.github.io/<repository>.

    danger

    Session data is downloaded to the user's local machine upon completion of the experiment when using GH Pages. Because of this, GH Pages is not suitable for fully online experiments.

    Setup

    Please follow the GitHub documentation for setting up GH Pages on your repository and make sure the publishing source for your repository is configured for gh-pages branch.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/github_discussions/index.html b/docs/3.3.x/github_discussions/index.html new file mode 100644 index 00000000..50be944b --- /dev/null +++ b/docs/3.3.x/github_discussions/index.html @@ -0,0 +1,16 @@ + + + + + +Github Discussions | Honeycomb + + + + +
    +
    Version: 3.3.x

    Github Discussions

    The Honeycomb repository includes a discussions board. It is a place to ask questions, share ideas, and engage with the community! Official announcements from the project are posted to the Announcements section.

    Please direct all feature requests and questions to the discussions board.

    Reporting Bugs

    Bugs with Honeycomb should be reported directly to the issues tab of the repository. Please select "Bug report" and include as much information as possible. If you are able to provide a minimal example that reproduces the bug, that is even better!

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/index.html b/docs/3.3.x/index.html new file mode 100644 index 00000000..6427ba1e --- /dev/null +++ b/docs/3.3.x/index.html @@ -0,0 +1,16 @@ + + + + + +Introduction | Honeycomb + + + + +
    +
    Version: 3.3.x

    Introduction

    Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that support lab equipment recordings and are ready for deployment to different settings (desktop or online) without significant changes to the code base.

    Flexible deployment online and in the lab

    Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

    Easy-to-install executables

    Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

    Foundation in jsPsych

    Honeycomb is built on top of jsPsych, a JavaScript library for running behavioral experiments in a web browser. jsPsych7 tasks can be moved directly into Honeycomb to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

    Community Driven

    Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

    Cite this work

    If you use Honeycomb in your work, please cite

    Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/javascript/index.html b/docs/3.3.x/javascript/index.html new file mode 100644 index 00000000..f733d8db --- /dev/null +++ b/docs/3.3.x/javascript/index.html @@ -0,0 +1,16 @@ + + + + + +JavaScript | Honeycomb + + + + + + + + + \ No newline at end of file diff --git a/docs/3.3.x/local_application/index.html b/docs/3.3.x/local_application/index.html new file mode 100644 index 00000000..e06adb67 --- /dev/null +++ b/docs/3.3.x/local_application/index.html @@ -0,0 +1,16 @@ + + + + + +Local Application | Honeycomb + + + + +
    +
    Version: 3.3.x

    Local Application

    A major feature of Honeycomb is the ability to bundle JsPsych tasks into applications that can be run on any computer in a lab or clinic. Installers for these applications can be created for Windows, Mac, and Linux. The applications can be run without an internet connection, and do not require any additional software to be installed on the computer.

    Installers for these applications can be created on demand and/or automatically when a new release is created. This is called "Continuous Deployment" - more information about Honeycomb's CI/CD workflow can be found here here.

    Creating a Release

    Follow the GitHub documentation for creating a release.

    The tag should be in the format vX.X.X where X.X.X is the version number of the release. For example, if the release is version 1.0.0, the tag should be v1.0.0.

    danger

    Your release must included a new tag for the CI/CD workflow to work.

    Installing the task

    1. Navigate to the repository's "Releases" tab and select the tag you created from above
    2. Download the correct installer for your operating system
    3. Double click the installer to run it. Follow the instructions to install the application.

    Running the Task

    The task can be run by double-clicking the application icon on the desktop.

    The local application will run the task in a full-screen window. This aims to prevent study participants from doing anything else on the computer while the task is running. However, the task can be exited if needed with the following shortcut:

    + Q

    Working with Data

    Data is automatically saved throughout the task and moved to a nested folder structure on the Desktop when the task is completed. Note how the folders are organized by studyID and participantID. Each session is saved as its own .json file; it's name is the timestamp of start_date of the task.

    Early Exits

    The run-through of an experiment in which the tasks exits prematurely will NOT be sent to the desktop. However, what data was collected is available in the user's "userData" folder which can be found in the following location:

    ~/Library/Application Support/honeycomb/TempData
    caution

    The .json file will likely not be formatted correctly because of the early exit. Take extra care to fix the file before using it for data analysis.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/npm_scripts/index.html b/docs/3.3.x/npm_scripts/index.html new file mode 100644 index 00000000..e226d3d4 --- /dev/null +++ b/docs/3.3.x/npm_scripts/index.html @@ -0,0 +1,16 @@ + + + + + +NPM Scripts | Honeycomb + + + + +
    +
    Version: 3.3.x

    NPM Scripts

    Custom scripts for common shell commands can be written in package.json and run via the node package manager (NPM). All of the commands needed to develop, build, and deploy Honeycomb are written as scripts.

    Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

    Executing an NPM Script
    npm run <script>

    Start

    • start runs the app in development mode and does NOT open a browser. This makes working with Electron easier as it creates its own browser for development.
    • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.
    • start:electron: Waits for the app to be running (from start) and then starts an electron process.

    Dev

    npm run dev runs the app in development mode on Electron. It executes start and start:electron concurrently.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run dev with different environment variables.

    • dev:home runs the app with equipment disabled.
    • dev:home:video runs the app with equipment disabled and video enabled.
    • dev:clinic runs the app with equipment enabled.
    • dev:clinic:video runs the app with equipment enabled and video enabled.
    • dev:turk-prolific runs the app with prolific and PsiTurk enabled.

    Firebase Development

    • dev:firebase runs the app with Firebase enabled.
    • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/.
    • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/.

    Working with Firebase is slightly different as it is meant to be run on the browser. npm run dev:firebase executes start:browser with Firebase enabled, which will automatically launch the running app in your default browser. It can be found on other browsers by navigating to localhost:3000.

    dev:firebase must be run in conjunction with firebase:emulators:start to work properly. This runs the Firebase Emulators locally with some dummy data. The emulator data can be viewed at localhost:4000.

    caution

    npm run firebase:emulators:start must be run in a separate terminal window that stays during development.

    tip

    The dummy study is s1 and the dummy participant is p1.

    Build

    npm run build creates a production build of the app in the build/ folder.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run build with different environment variables.

    • build:home builds the app with equipment disabled
    • build:home:video builds the app with equipment disabled and video enabled
    • build:clinic builds the app with equipment enabled
    • build:clinic:video builds the app with equipment enabled and video enabled
    • build:firebase builds the app with Firebase enabled
    • build:turk-prolific builds the app with prolific and PsiTurk enabled

    Package

    npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

    • npm run package:windows
    • npm run package:linux
    • npm run package:mac
    info

    Packaging for Windows on a non-Windows machine requires mono and wine to be installed.

    Miscellaneous

    • cli runs the Firebase CLI script.
    • commit runs Commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
    • format uses Prettier to style code in a consistent format.
    • lint uses Eslint to find problems in the code.
    • postinstall is run automatically after npm install and is used to rebuild the Electron dependencies
    • prepare is run automatically before the project is packaged/installed and is used to set up the project's pre-commit hooks
    • prebuild is run automatically before npm run build and is used to rebuild the Electron dependencies
    + + + + \ No newline at end of file diff --git a/docs/3.3.x/prerequisites/index.html b/docs/3.3.x/prerequisites/index.html new file mode 100644 index 00000000..f9472ad3 --- /dev/null +++ b/docs/3.3.x/prerequisites/index.html @@ -0,0 +1,16 @@ + + + + + +Prerequisites | Honeycomb + + + + +
    +
    Version: 3.3.x

    Prerequisites

    It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install. This page details what programs and packages are needed to run and build Honeycomb. There are some OS-specific prerequisites needed to build a task as a desktop application.

    OS Independent

    Git

    git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

    GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

    Node Version Manager

    NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

    Python

    Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

    danger

    Honeycomb cannot use Python version 3.12 or newer. The installers will install version 3.11.

    Oracle JDk

    Java is another high-level programming language that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

    note

    Honeycomb needs Java version 11 or later to run - the installers use version 18.

    Visual Studio Code

    Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

    Mac-specific Installs

    X-Code

    XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

    Installing XCode
      xcode-select --install

    Rosetta

    Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple Silicon system.

    Windows-specific Install

    Visual Studio

    Visual Studio is a special IDE for the Windows platform. It comes with everything needed to compile desktop applications from a PC. Visual Studio Community is free to use.

    caution

    The "Desktop development with C++" workload must also be installed with Visual Studio. The automated installers should preselect this but you should double check to be certain!

    Manual Installation

    macOS

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Windows

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Linux

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

    Further Help

    If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/prolific/index.html b/docs/3.3.x/prolific/index.html new file mode 100644 index 00000000..145b4f3a --- /dev/null +++ b/docs/3.3.x/prolific/index.html @@ -0,0 +1,16 @@ + + + + + +Prolific | Honeycomb + + + + +
    +
    Version: 3.3.x

    Prolific

    Prolific Setup

    caution

    Prolific integration is only available in Honeycomb for tasks deployed to Firebase.

    Please follow the discussion post Configure participant and study ID in prolific to configure a Prolific study that integrates with Honeycomb.

    • The "Prolific ID" should be set to participantID
    • The "Study ID" should be set to studyID
    • The "Session ID" should be set to SESSION_ID

    Further Reading

    The jsPsych Documentation also provides a guide for Prolific integration. Please note that this documentation will differ slightly from the Honeycomb integration.

    + + + + \ No newline at end of file diff --git a/docs/3.3.x/psiturk/index.html b/docs/3.3.x/psiturk/index.html new file mode 100644 index 00000000..ac18e253 --- /dev/null +++ b/docs/3.3.x/psiturk/index.html @@ -0,0 +1,17 @@ + + + + + +PsiTurk | Honeycomb + + + + +
    +
    Version: 3.3.x

    PsiTurk

    While Honeycomb is optimized for use on a local application, we added functionality for usage with PsiTurk. The application will detect if it's being used in a Turk environment and will save the data to the default PsiTurk SQLite database.

    Prebuilt version

    When a GitHub Action is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts. The workflows responsible for building the PsiTurk application are .github/workflows/package.yml and .github/workflows/release.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

    If this is all you need, the build instructions below can be skipped!

    Build instructions

    To set up your PsiTurk project, we provide a script that does the conversion. +PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

    You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

    • Build the application: npm run build

    • Move to the psiturkit directory: cd psiturkit

    • If it's the first time you're running the script:

      ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>
    • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):

      ./psiturk-it -U -p <PATH_TO_NEW_PSITURK_PROJECT>

    Running PsiTurk

    After that, just navigate to your newly created PsiTurk project directory.

    shell> psiturk # start psiturk
    psiturk> server on # start server
    psiturk> debug # enter debug mode
    + + + + \ No newline at end of file diff --git a/docs/3.3.x/quick_start/index.html b/docs/3.3.x/quick_start/index.html new file mode 100644 index 00000000..36092d20 --- /dev/null +++ b/docs/3.3.x/quick_start/index.html @@ -0,0 +1,16 @@ + + + + + +Quick Start | Honeycomb + + + + +
    +
    Version: 3.3.x

    Quick Start

    Creating Your Task Repository

    The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

    1. Go to the Honeycomb repository

    2. Click on Use this template and select Create a new repository.

      Use this template
    3. Enter the owner, name, and description of your repository and click on Create repository from template.

      Create the repository
      note

      We recommend creating a public repository and leaving Include all branches unchecked

    4. Ensure the repository's workflow permissions are set to "Read and write permissions"

      Settings -> Actions -> General -> Workflow permissions

      GitHub workflow permissions settings

    Additional details about template repositories can be found on the Github Docs.

    Cloning the Repository

    With the repository now setup it can be cloned onto your computer.

    1. Navigate to the repository on GitHub.

    2. Click the Code button and copy the URL

      GitHub clone repo button
    3. Open a terminal and navigate to where you want the cloned directory

    Terminal.app
    cd 'path/to/directory'
    1. Clone the repo with the following command
    Paste the URL you copied earlier
     git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
    note

    Git can be downloaded here if it is not already on your system.

    Additional details and alternative methods for cloning a repository can be found on the Github Docs.

    Installing Prerequisites

    All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

    See Prerequisites for more information about these programs.

    Initial Install

    The most commonly used package manager on macOS is Homebrew.

    1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

      /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    2. Paste the following command and follow the prompts to install the listed programs:

      brew bundle
    3. Install Xcode (not available on Homebrew)

      xcode-select --install
    note

    If you are running into issues after installing the packages, please restart your terminal and/or reboot your computer. This should resolve most issues.

    Setting Up Node

    NVM (Node Version Manager) is a tool for installing and using multiple versions on Node on your computer. It must first be installed:

    1. Install NVM

      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
    2. Copy the version number listed in .nvmrc.

      .nvmrc file
    3. Install that version.

      nvm install <VERSION>
    4. Use the needed version.

      nvm use <VERSION>
    5. Set the current version as your default

      nvm alias default node
      note

      You can skip this step if you've already set a default node version in a different project.

    Install Dependencies

    There are many Node packages used by Honeycomb that also need to be installed. Node comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

    Install Honeycomb's dependencies
    npm install

    Certain Node dependencies are best installed globally. These tools will be available from the command line anywhere on your system.

    Install Honeycomb's global dependencies
    npm install -g electron firebase-tools dotenv-cli electron lint-staged

    Run the Task

    Run the task in development mode
    npm run dev

    Running the task in development mode enables "hot reloading": changes to the code will immediately be reflected in the app without needing to restart the server.

    tip

    The dev script runs Honeycomb on Electron without any environment variables. Check out the NPM Scripts page for more information on the available development environments.

    note

    Honeycomb ships with a modified version of the "simple reaction time task" from the jsPsych tutorial. In the next section we'll create a new task and tell Honeycomb to run it!

    Edit the Task

    Now that the project is up and running we can make our first changes to the code!

    info

    The quick start guide details a command line workflow for version control. If you are unfamiliar with Git, we recommend reading the linked page before proceeding.

    1) Edit the Project Metadata

    1. Create a new branch in a separate terminal

      Create the branch edit-package-json
      git checkout -b edit-package-json
    2. Open package.json and edit it to reflect your app:

      1. name is your task's name, generally this is the name of our repository
      2. description should be rewritten to better match your task
      3. author is your lab (or PIs) name, email, and website
      4. honeycombVersion is the number currently in the version field
      5. version should then be reset to 1.0.0
      6. repository is the link the GitHub repository you created earlier.
      package.json
      {
      "name": "my-task",
      "description": "A custom task for the Honeycomb platform",
      "author": {
      "name": "My Lab",
      "email": "example@domain.com",
      "url": "https://lab-web-page.com"
      },
      "honeycombVersion": "3.3.0", // Match what was in version!
      "version": "3.3.0",
      "version": "1.0.0",
      "repository": "https://github.com/my-username/my-repository"
      },
    3. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "edit package.json with my task's information"
    4. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    2) Add a file for the task

    1. Bring your branch up to date with the main branch

      Switch to the main branch
      git checkout main
      Bring changes from GitHub into your local repository
      git pull
    2. Create a new branch (replace task-name with the name of your task)

      Check out a new branch
      git checkout -b add-<task-name>-file
    3. Add a new file inside src/experiment/ with the same name as your task

    4. Save your changes and commit them to git:

      Add the new file to Git
      git add .
      Commit all changed files with a custom message
      git commit -a -m "feat: adds file for the <task name> task"
    5. Add a taskNameOptions object to the new file (replace taskName with the name of your task)

      taskName.js
      /**
      * Experiment-wide settings for jsPsych: https://www.jspsych.org/7.3/overview/experiment-options/
      * Note that Honeycomb combines these with other options required for Honeycomb to operate correctly
      */
      export const taskNameOptions = {
      // Called when every trial finishes
      on_trial_finish: function (data) {
      console.log(`Trial ${data.internal_node_id} just finished:`, data);
      },
      // Called when the experiment finishes
      on_finish: function (data) {
      console.log("The experiment has finished:", data);
      // Reload the page for another run-through of the experiment
      window.location.reload();
      },
      };
    6. Add a buildTaskNameFunction to the new file (replace TaskName with the name of your task)

      taskName.js
      /**
      * This timeline builds the example reaction time task from the jsPsych tutorial.
      * Take a look at how the code here compares to the jsPsych documentation!
      * See the jsPsych documentation for more: https://www.jspsych.org/7.3/tutorials/rt-task/
      *
      * @param {Object} jsPsych The jsPsych instance being used to run the task
      * @returns {Object} A jsPsych timeline object
      */
      export function buildTaskNameTimeline(jsPsych) {}
    7. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds taskNameOptions and buildTaskNameTimeline to taskName.js"
    8. Edit src/experiment/index.js to use the new file

      src/experiment/index.js
      import { buildHoneycombTimeline, honeycombOptions } from "./honeycomb";
      import { buildTaskNameTimeline, taskNameOptions } from "./taskName";

      // ...

      export const jsPsychOptions = honeycombOptions;
      export const jsPsychOptions = taskNameOptions;

      // ...

      export function buildTimeline(jsPsych, studyID, participantID) {
      console.log(`Building timeline for participant ${participantID} on study ${studyID}`);

      const timeline = buildHoneycombTimeline(jsPsych);
      const timeline = buildTaskNameTimeline(jsPsych);
      return timeline;
      }
    9. Run the format script to make sure the code is formatted correctly

      npm run format
    10. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "fix: Use new task's file"
    11. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    3) Add some trials to the task

    1. Bring your branch up to date with the main branch

      Switch to the main branch
      git checkout main
      Bring changes from GitHub into your local repository
      git pull
    2. Create a new branch

      Bring changes from GitHub into your local repository
      git checkout -b add-start-procedure
    3. Add the start procedure to the buildTaskNameTimeline function in the file you created earlier

      taskName.js
      import { buildStartProcedure } from "./procedures/startProcedure";

      // ...

      export function buildTaskNameTimeline(jsPsych) {
      // Build the trials that make up the start procedure
      const startProcedure = buildStartProcedure(jsPsych);

      const timeline = [startProcedure];
      return timeline;
      }

      // ...
    4. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds startProcedure to the task"
    5. Edit the text for the task's name

      src/config/language.json
      {
      "name": "taskName"
      // ...
      }
      tip

      The text for the introduction trial is in src/config/language.json under the trials and introduction key.

      src/config/language.json
       {
      "name": "taskName"
      // ...
      "trials": {
      "introduction": "Welcome to the experiment. Press any key to begin."
      // ...
      },
      // ...
      }
    6. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: Updates the language for the startProcedure of the task"
    7. Add the end procedure to the buildTaskNameTimeline function in the file you created earlier

      taskName.js
      import { buildStartProcedure } from "./procedures/startProcedure";
      import { buildEndProcedure } from "./procedures/endProcedure";

      // ...

      export function buildTaskNameTimeline(jsPsych) {
      // Build the trials that make up the start procedure
      const startProcedure = buildStartProcedure(jsPsych);

      // Builds the trials that make up the end procedure
      const endProcedure = buildEndProcedure(jsPsych);

      const timeline = [startProcedure, endProcedure];
      return timeline;
      }
      // ...
      tip

      The text for the conclusion trial is in src/config/language.json under the trials and conclusion key.

      src/config/language.json
       {
      "name": "taskName"
      // ...
      "trials": {
      // ...
      "conclusion": "Welcome to the experiment. Press any key to begin."
      },
      }
    8. Run a format to make sure the code is formatted correctly

      npm run format
    9. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds endProcedure to the task"
    10. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    Next Steps

    • The Firebase page explains how to set up your task with Firebase.
    • The Environment Variables page explains how to configure your task for deployment to multiple scenarios.
    • The NPM Scripts page lists every script you can run and which environment they use.
    + + + + \ No newline at end of file diff --git a/docs/3.3.x/troubleshooting/index.html b/docs/3.3.x/troubleshooting/index.html new file mode 100644 index 00000000..6954028c --- /dev/null +++ b/docs/3.3.x/troubleshooting/index.html @@ -0,0 +1,16 @@ + + + + + +Troubleshooting | Honeycomb + + + + +
    +
    Version: 3.3.x

    Troubleshooting

    Inspecting Errors

    When running any of the npm run dev commands you may encounter errors. These may display over the window itself or may may exist in the developer tools. These tools can be accessed by right clicking the window and selecting "Inspect" or by pressing Ctrl+Shift+I (Cmd+Option+I on Mac). The errors, as well as any console.logs, will be displayed in the "Console" tab of the developer tools.

    When developing Electron apps there are two processes: main, and renderer. In this case, main corresponds to public/electron/main.js and its console is in the terminal where npm run devwas run. renderer corresponds to the React App - this is everything else. This console can be found using the same steps as above - note that running npm run dev should open the developer console by default.

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Most npm issues can be resolved by re-installing dependencies. This can be done by running the following commands in the root directory of the project:

    1. Delete the node_modules/ folder
    2. Delete hte package-lock.json file
    3. Reinstall dependencies
      npm install
    + + + + \ No newline at end of file diff --git a/docs/3.3.x/variants/index.html b/docs/3.3.x/variants/index.html new file mode 100644 index 00000000..134107ee --- /dev/null +++ b/docs/3.3.x/variants/index.html @@ -0,0 +1,16 @@ + + + + + +Variants | Honeycomb + + + + +
    +
    Version: 3.3.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    + + + + \ No newline at end of file diff --git a/docs/3.3.x/version_control/index.html b/docs/3.3.x/version_control/index.html new file mode 100644 index 00000000..a6025f5c --- /dev/null +++ b/docs/3.3.x/version_control/index.html @@ -0,0 +1,16 @@ + + + + + +Version Control | Honeycomb + + + + +
    +
    Version: 3.3.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, with the exception of a few used to synchronize with the GitHub remote host. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branches diagram

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    Create a pull requestAdd reviewers to a pull request

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button. Note how the branch name describes the changes.

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main
    • Perform tests and code reviews before merges into main, not afterwards
    • Every branch starts from main, and targets main
    • Commit messages reflect intent

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout -b <branch>create and checkout a new branch
    git checkout <branch>checkout the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    GUI Based Source Control

    • VS Code is the default IDE installed by Honeycomb. Check out this overview of source control in VS Code!
    • GitHub Desktop is a GUI application built specifically for working with Git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes from the template repository. It is tedious, but extremely import, to not accidentally overwrite your task when resolving these conflicts.

    + + + + \ No newline at end of file diff --git a/docs/ci_cd/index.html b/docs/ci_cd/index.html index e3b45522..46be391d 100644 --- a/docs/ci_cd/index.html +++ b/docs/ci_cd/index.html @@ -3,14 +3,14 @@ -Continuous Integration / Deployment | Honeycomb - - +Continuous Integration / Deployment | Honeycomb + +
    -
    Version: 3.3.x

    Continuous Integration / Deployment

    Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs.

    What are Github Actions

    GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

    GitHub Actions are written as YML files inside the .github/workflows/ folder of your repository.

    Honeycomb's CI/CD Workflows

    Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:

    • Home: The app does not expect event code triggers and photodiode spots.
    • Clinic: The app expects event code triggers and photodiode spots.
    tip

    Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.

    • pull_request.yaml: Every time a Pull Request (PR) is created the software is built and tests are run for all platforms with home and clinic settings. This workflow does not upload desktop installers.

    • release.yml: Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.

    • workflow-package.yaml: Create installers for any/all platforms for the home and/or clinic setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.

      note

      On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their official documentation.

    • workflow-delete-artifacts.yaml: On-demand workflow for deleting artifacts form your GitHub repository. This can be useful when the package.yaml workflow is run multiple times and you want to delete the artifacts from previous runs.

    Firebase

    • firebase-hosting-merge.yaml: Deploys the web version of the application to Firebase when a PR is merged into the main branch.
    • firebase-hosting-pull-request.yaml: Creates a preview version of the application with Firebase when a PR is opened.
      danger

      While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.

    note

    These workflows may be safely deleted if you are not planning to ever use Firebase.

    - - +
    Version: 3.4.x

    Continuous Integration / Deployment

    Honeycomb leverages Continuous Integration/Deployment (CI/CD) to build the code and installers for different operating systems and settings, both on demand and automatically as code is pushed to the repository. Honeycomb's CI/CD is managed by GitHub Actions. These workflows provide Honeycomb's foundation and can easily be modified or extended to meet more needs.

    What are Github Actions

    GitHub Actions automate tasks within the development life cycle of your software. GitHub Actions consist of a series of commands that run after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command to build and test your software. You can learn more about the events that trigger workflows in GitHub's documentation

    GitHub Actions are written as YML files inside the .github/workflows/ folder of your repository.

    Honeycomb's CI/CD Workflows

    Honeycomb includes workflows to build and create installers for Windows, Mac and Linux, as well as for deploying to Firebase. These workflows exist for two configurations of the tasks:

    • Home: The app does not expect event code triggers and photodiode spots.
    • Clinic: The app expects event code triggers and photodiode spots.
    tip

    Event code triggers and photodiode spots can only be used on local applications! They will not appear when Honeycomb is deployed on the web.

    • pull_request.yaml: Every time a Pull Request (PR) is created the software is built and tests are run for all platforms with home and clinic settings. This workflow does not upload desktop installers.

    • release.yml: Every time a release is created, edited, or published installers for the Honeycomb app are created and uploaded to the release. This also builds a PsiTurk version and deploys the app to GitHub pages.

    • workflow-package.yaml: Create installers for any/all platforms for the home and/or clinic setting on demand. The installers/executables are uploaded as artifacts and are available for download from the GitHub Actions tab. This also builds a PsiTurk version when linux or all operating systems are selected.

      note

      On-demand workflows are triggered manually from the GitHub Actions tab. Each GitHub organization/individual has a quota on storage in private repositories. Uploading artifacts counts against your quota. You may consider configuring your workflows to only upload what you need. You can learn more about GitHub's storage limits in their official documentation.

    • workflow-delete-artifacts.yaml: On-demand workflow for deleting artifacts form your GitHub repository. This can be useful when the package.yaml workflow is run multiple times and you want to delete the artifacts from previous runs.

    Firebase

    • firebase-hosting-merge.yaml: Deploys the web version of the application to Firebase when a PR is merged into the main branch.
    • firebase-hosting-pull-request.yaml: Creates a preview version of the application with Firebase when a PR is opened.
      danger

      While this workflow uses a preview link it does use the production database. Ensure you use a test study to not conflict with your participant data.

    note

    These workflows may be safely deleted if you are not planning to ever use Firebase.

    + + \ No newline at end of file diff --git a/docs/directory_structure/index.html b/docs/directory_structure/index.html index 163c8712..cc6025dd 100644 --- a/docs/directory_structure/index.html +++ b/docs/directory_structure/index.html @@ -3,15 +3,15 @@ -Directory Structure | Honeycomb - - +Directory Structure | Honeycomb + +
    -
    Version: 3.3.x

    Directory Structure

    This project directory is organized to be modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used, and only the pieces of code needed for any given file should be imported.

    assets/

    This folder contains static files that are used by the application. Honeycomb uses a few images as icons for the installed applications.

    caution

    Assets that pertain to your specific task should be added to the public/assets/ folder, not here!

    build/

    The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds.

    caution

    build/ should be left alone! It is in Honeycomb's .gitignore and should never be added to git.

    emulator_data/

    This folder contains starter data for the Firebase Emulators to use while developing locally. The Firebase Scripts detail how to use this data.

    caution

    emulator_data/ is written to when running npm run firebase:emulators:save and should never be edited.

    env/

    This folder contains different files used to pass environment variables (settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

    node_modules/

    caution

    node_modules/ is written to when running npm install and should never be edited. It is in Honeycomb's .gitignore and should never be added to git.

    psiturkit/

    The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see PsiTurk for more information.

    caution

    This folder involves a Honeycomb deployment. The files do not need to be edited.

    public/

    The public directory contains files that are used as assets in the built app.

    • index.html is the entry point of the website
      • Changing <title>Honeycomb</title> will update the text in the browser tab!
    • favicon.ico is the small (16x16px) icon you can see in the browser tab
    • manifest.json contains metadata about the web app
    caution

    manifest.json involves project metadata and does not need to be edited.

    assets/

    The public/assets/ directory contains all of the audio, images, and videos needed to run your task.

    electron/

    The public/electron/ directory contains the files needed to run Honeycomb as an Electron app.

    • main.js sets up Electron itself
    • preload.js sets up the communication between the main and renderer processes.
    caution

    This folder involves a Honeycomb deployment, the files do not need to be edited.

    lib/

    The public/lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags.

    caution

    This folder involves dependencies for a Honeycomb deployment, the files should not be edited.

    src/

    This folder contains the source code for the Honeycomb application.

    • index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:
      <div id="root"></div>
      caution

      index.js runs Honeycomb itself and should not be edited.

    App/

    Files relating to the React application.

    caution

    This folder holds the code that runs the jsPsych task, the files do not need to be edited.

    components/

    The React components that make up Honeycomb are located here.

    • App.jsx initializes and maintains the state of the application.
    • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
    • JsPsychExperiment.jsx initializes the jsPsych experiment.
    • Login.jsx handles user authentication based on the environment variables passed to Honeycomb.

    deployments/

    Custom code used by the various deployments such as Firebase.

    caution

    This folder involves Honeycomb deployments, the files do not need to be edited.

    config/

    Each file in the config directory contains settings for a different part of the task.

    • language.json contains the language used in your task. This file allows for easy internationalization of the task (e.g. English and Spanish) and mturk-specific language. Common phrases can be written once and re-used throughout the task.

    • main.js contains the global settings (e.g., whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate files.

    • settings.json contains the settings for your task. Usage of the config file allows for easy updating of task settings. Common settings can be written once and re-used throughout the task.

    • trigger.js contains equipment-related settings for a trigger box. The eventCodes are especially important for marking the types of given trials.

    experiment/

    tip

    This is where you'll spend most of your time while developing your task!

    • index.js contains the outermost logic for running the experiment. It loads experiment's styling and exports the main timeline and options for the experiment.
      caution

      The experiment will not run correctly if the names jsPsychOptions or buildTimeline are changed.

    • honeycomb.js contains the options and timeline for the jsPsych tutorial's "Simple React Time Task". It serves as an example for the experiment timeline for your task.
      tip

      This is just an example experiment! Be sure to write your experiment in its own file. -{/ TODO: Link to this in the quick_start guide once it's ready /}

    procedures/

    A procedure is a tested timeline of trials in jsPsych. Common parameters can be used across trials, and the trials within a procedure can be ordered and repeated as desired. Check out the JsPsych documentation for more information on creating a custom procedure.

    • startProcedure.js contains the procedure for the start of the experiment. It uses the environment and task settings from config.json to create a nested timeline that correctly starts the experiment.
    • honeycombProcedure.js contains the procedure for the Honeycomb task. It displays a fixation dot and presents the stimulus of the example task.
      tip

      This is just an example procedure! Be sure to write your procedures in their own files.

    • endProcedure.js contains the procedure for the end of the experiment. It uses the environment and task settings from config.json to create a nested timeline that correctly end the experiment.

    trials/

    A trial is the base unit of an experiment. These trials are ordered into procedures and timelines to create the task itself.

    • adjustVolume.js prompts the user to adjust the volume on their tablet.

    • camera.js contains trials for beginning and ending a camera recording.

    • conclusion.js displays a message to the user indicating that the experiment has concluded.

    • fixation.js displays a fixation dot in the center of the screen. It contains additional logic for flashing a photodiode spot and emitting an event code based on the environment settings.

    • fullscreen.js contains trials for entering and exiting fullscreen mode.

    • holdUpMarker.js prompts the user to connect their event marker and hold it up to the camera.

    • honeycombTrials.js contains the individual trials used in the Honeycomb task. These trials are imported into experiment/procedures/honeycombProcedure.js and experiment/honeycomb.js.

      tip

      These trials are for the example experiment! Be sure to write trials pertaining to your task in their own file(s).

    • introduction.js displays a message to the user welcoming them to the experiment. They must click on a button to continue.

    • name.js displays the name of the task to the user.

    • startCode.js emits a start code to a photodiode spot and audible beep.

    • survey.js contains trials pertaining to a survey/quiz for the user to complete.

    lib/

    A library of utility and markup functions are located here. This allows for functions and html to be re-used wherever needed.

    • utils.js contains utility functions that can be used across a variety of trials. Be sure to look for functions you might be able to use in your task!

    markup/

    Markup files contain HTML templates used throughout the task.

    • photodiode.js contains the markup for the photodiode box and spot displayed in the bottom right corner of the screen
    • tags.js contains functions for wrapping language in common html tags. You should always wrap your language in a tag to ensure it is displayed correctly.
      • For example: p('Hello World') will return <p>Hello World</p>.
    tip

    The tag function inside tags.js can be used to wrap language in any html tag you need.

    Other Folders/Files

    • .nvmrc determines which version of node that Honeycomb is designed to be run on.

    • .github/workflows/ contains .yaml files used for CI/CD with GitHub Actions.

    • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.

    • cli.mjs is the script used to download and delete data stored in Firestore.

    • version.js is the script used to keep track of which version of the task a given experiment is using.

    caution

    cli.mjs and version.js are automated scripts and should not be edited.

    package-lock.json is written to when running npm install and should never be edited.

    Firebase Files

    • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
    • firebase.json contains the Firebase settings for Honeycomb.
    • firestore.indexes.json contains the Firestore index settings for Honeycomb.
    • firestore.rules contains the Firestore rules for creating/editing data.
    caution

    firebase.json and firestore.indexes.json are default configs and shouldn't need to be edited.

    Git Files

    • .gitignore lists the folders and files that should be excluded from Git.
    caution

    Any secrets and/or tokens must be added to .gitignore or they will be visible to anyone with access to the repository!

    Eslint Files

    • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal preference.
    • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

    Prettier Files

    .prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal preference.

    - - +
    Version: 3.4.x

    Directory Structure

    This project directory is organized to be modular and composable. In general, files and functions should be relatively small and self-contained, global scope should not be used, and only the pieces of code needed for any given file should be imported.

    assets/

    This folder contains static files that are used by the application. Honeycomb uses a few images as icons for the installed applications.

    caution

    Assets that pertain to your specific task should be added to the public/assets/ folder, not here!

    build/

    The build scripts automatically create a build folder at the root of the repository and update it on subsequent builds.

    caution

    build/ should be left alone! It is in Honeycomb's .gitignore and should never be added to git.

    emulator_data/

    This folder contains starter data for the Firebase Emulators to use while developing locally. The Firebase Scripts detail how to use this data.

    caution

    emulator_data/ is written to when running npm run firebase:emulators:save and should never be edited.

    env/

    This folder contains different files used to pass environment variables (settings) into Honeycomb. Honeycomb starts with presets for common use cases and is explained in greater detail in the Environment Variables section.

    node_modules/

    caution

    node_modules/ is written to when running npm install and should never be edited. It is in Honeycomb's .gitignore and should never be added to git.

    psiturkit/

    The file psiturk-it inside psiturkit/ is a bash script used to instal PsiTurk locally - see PsiTurk for more information.

    caution

    This folder involves a Honeycomb deployment. The files do not need to be edited.

    public/

    The public directory contains files that are used as assets in the built app.

    • index.html is the entry point of the website
      • Changing <title>Honeycomb</title> will update the text in the browser tab!
    • favicon.ico is the small (16x16px) icon you can see in the browser tab
    • manifest.json contains metadata about the web app
    caution

    manifest.json involves project metadata and does not need to be edited.

    assets/

    The public/assets/ directory contains all of the audio, images, and videos needed to run your task.

    electron/

    The public/electron/ directory contains the files needed to run Honeycomb as an Electron app.

    • main.js sets up Electron itself
    • preload.js sets up the communication between the main and renderer processes.
    caution

    This folder involves a Honeycomb deployment, the files do not need to be edited.

    lib/

    The public/lib/ directory contains the files PsiTurk needs to run. Note that index.html references these files inside the <script> tags.

    caution

    This folder involves dependencies for a Honeycomb deployment, the files should not be edited.

    src/

    This folder contains the source code for the Honeycomb application.

    • index.js is the entry point for React in our application. Note that the id 'root' corresponds with a tag in public/index.html:
      <div id="root"></div>
      caution

      index.js runs Honeycomb itself and should not be edited.

    App/

    Files relating to the React application.

    caution

    This folder holds the code that runs the jsPsych task, the files do not need to be edited.

    components/

    The React components that make up Honeycomb are located here.

    • App.jsx initializes and maintains the state of the application.
    • Error.jsx displays a small error message. It is rendered when the App.jsx detects an issue in state.
    • JsPsychExperiment.jsx initializes the jsPsych experiment.
    • Login.jsx handles user authentication based on the environment variables passed to Honeycomb.

    deployments/

    Custom code used by the various deployments such as Firebase.

    caution

    This folder involves Honeycomb deployments, the files do not need to be edited.

    config/

    Each file in the config directory contains settings for a different part of the task.

    • language.json contains the language used in your task. This file allows for easy internationalization of the task (e.g. English and Spanish) and mturk-specific language. Common phrases can be written once and re-used throughout the task.

    • main.js contains the global settings (e.g., whether Honeycomb is running online or in the clinic) passed from env variables and logic for loading the appropriate files.

    • settings.json contains the settings for your task. Usage of the config file allows for easy updating of task settings. Common settings can be written once and re-used throughout the task.

    • trigger.js contains equipment-related settings for a trigger box. The eventCodes are especially important for marking the types of given trials.

    experiment/

    tip

    This is where you'll spend most of your time while developing your task!

    • index.js contains the outermost logic for running the experiment. It loads experiment's styling and exports the main timeline and options for the experiment.
      caution

      The experiment will not run correctly if the names jsPsychOptions or buildTimeline are changed.

    • honeycomb.js contains the options and timeline for the jsPsych tutorial's "Simple React Time Task". It serves as an example for the experiment timeline for your task.
      tip

      This is just an example experiment! Be sure to write your experiment in its own file. +{/ TODO: Link to this in the quick_start guide once it's ready /}

    procedures/

    A procedure is a tested timeline of trials in jsPsych. Common parameters can be used across trials, and the trials within a procedure can be ordered and repeated as desired. Check out the JsPsych documentation for more information on creating a custom procedure.

    • startProcedure.js contains the procedure for the start of the experiment. It uses the environment and task settings from config.json to create a nested timeline that correctly starts the experiment.
    • honeycombProcedure.js contains the procedure for the Honeycomb task. It displays a fixation dot and presents the stimulus of the example task.
      tip

      This is just an example procedure! Be sure to write your procedures in their own files.

    • endProcedure.js contains the procedure for the end of the experiment. It uses the environment and task settings from config.json to create a nested timeline that correctly end the experiment.

    trials/

    A trial is the base unit of an experiment. These trials are ordered into procedures and timelines to create the task itself.

    • adjustVolume.js prompts the user to adjust the volume on their tablet.

    • camera.js contains trials for beginning and ending a camera recording.

    • conclusion.js displays a message to the user indicating that the experiment has concluded.

    • fixation.js displays a fixation dot in the center of the screen. It contains additional logic for flashing a photodiode spot and emitting an event code based on the environment settings.

    • fullscreen.js contains trials for entering and exiting fullscreen mode.

    • holdUpMarker.js prompts the user to connect their event marker and hold it up to the camera.

    • honeycombTrials.js contains the individual trials used in the Honeycomb task. These trials are imported into experiment/procedures/honeycombProcedure.js and experiment/honeycomb.js.

      tip

      These trials are for the example experiment! Be sure to write trials pertaining to your task in their own file(s).

    • introduction.js displays a message to the user welcoming them to the experiment. They must click on a button to continue.

    • name.js displays the name of the task to the user.

    • startCode.js emits a start code to a photodiode spot and audible beep.

    • survey.js contains trials pertaining to a survey/quiz for the user to complete.

    lib/

    A library of utility and markup functions are located here. This allows for functions and html to be re-used wherever needed.

    • utils.js contains utility functions that can be used across a variety of trials. Be sure to look for functions you might be able to use in your task!

    markup/

    Markup files contain HTML templates used throughout the task.

    • photodiode.js contains the markup for the photodiode box and spot displayed in the bottom right corner of the screen
    • tags.js contains functions for wrapping language in common html tags. You should always wrap your language in a tag to ensure it is displayed correctly.
      • For example: p('Hello World') will return <p>Hello World</p>.
    tip

    The tag function inside tags.js can be used to wrap language in any html tag you need.

    Other Folders/Files

    • .nvmrc determines which version of node that Honeycomb is designed to be run on.

    • .github/workflows/ contains .yaml files used for CI/CD with GitHub Actions.

    • package.json contains metadata about your project, a list of the dependencies needed for the project, and scripts to run tasks related to your task. The Quick Start lists which metadata should be changed.

    • cli.mjs is the script used to download and delete data stored in Firestore.

    • version.js is the script used to keep track of which version of the task a given experiment is using.

    caution

    cli.mjs and version.js are automated scripts and should not be edited.

    package-lock.json is written to when running npm install and should never be edited.

    Firebase Files

    • .firebaserc contains the name of the project Firebase should connect to. Be sure to update the default project to the one you created!
    • firebase.json contains the Firebase settings for Honeycomb.
    • firestore.indexes.json contains the Firestore index settings for Honeycomb.
    • firestore.rules contains the Firestore rules for creating/editing data.
    caution

    firebase.json and firestore.indexes.json are default configs and shouldn't need to be edited.

    Git Files

    • .gitignore lists the folders and files that should be excluded from Git.
    caution

    Any secrets and/or tokens must be added to .gitignore or they will be visible to anyone with access to the repository!

    Eslint Files

    • .eslintrc.js contains the Eslint settings for Honeycomb. We recommend it's left alone but can be adjusted for personal preference.
    • .eslintignore lists the folders and files that eslint shouldn't touch, similar to .gitignore.

    Prettier Files

    .prettierrc.js contains the Prettier settings for Honeycomb. We recommend it's left alone but can be adjusted for personal preference.

    + + \ No newline at end of file diff --git a/docs/environment_variables/index.html b/docs/environment_variables/index.html index 202664dc..2429303c 100644 --- a/docs/environment_variables/index.html +++ b/docs/environment_variables/index.html @@ -3,14 +3,14 @@ -Environment Variables | Honeycomb - - +Environment Variables | Honeycomb + +
    -
    Version: 3.3.x

    Environment Variables

    Honeycomb uses environment variables to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text.

    NameDesktop vs OnlineBuild vs Run-timeDefault ValueTypeDescription
    REACT_APP_FIREBASEonlinebuildFalsebooleanIf the task is saving its data on Firebase.
    REACT_APP_VIDEOdesktopbuildFalsebooleanIf the participant is being video recorded.
    REACT_APP_USE_EEGdesktopbuildFalsebooleanIf the EEG (Event Marker) is available and recording.
    REACT_APP_USE_PHOTODIODEdesktopbuildFalsebooleanIf the photodiode spot is in use.
    REACT_APP_USE_VOLUMEdesktop onlinebuildFalsebooleanIf the participant should be asked to adjust their volume. (e.g. the task is using sound)
    REACT_APP_STUDY_IDdesktop onlinerun""stringThe id of a study. User will enter this value in the login screen if not set.
    REACT_APP_PARTICIPANT_IDdesktop onlinerun""stringThe id of a participant. User will enter this value in the login screen if not set.
    EVENT_MARKER_PRODUCT_IDdesktoprun""stringThe product ID of the event marker. If not set, it will default to the productID set in public/config/trigger.js. If neither are set, it will attempt to connect using the COM name.
    EVENT_MARKER_COM_NAMEdesktoprun"COM3"stringThe COM name of the event marker. If not set, it will use the comName set in public/config/trigger.js. Field is ignored if EVENT_MARKER_PRODUCT_ID is set.
    note

    Note that Honeycomb does use other environment variables (e.g., ELECTRON_START_URL) but they do not effect the task itself. They can be safely ignored.

    Understanding the Environment Variables

    Run-time

    The run badge indicates the variable is set/determined each time the executable is run. Run-time environment variables allow for quick changes when running the task. They are convenient since they don't require building a whole different executable.

    • Desktop deployments must set these environment variables at the system level.
    • Online deployments must use Firebase, and store the runtime environment variables in Firestore.

    Build-time

    The build badge indicates the variable is set during the build phase (npm run build) and cannot be changed at run-time. These variables are configured via .env files in the env folder.

    The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

    package.json
    "[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]"

    See NPM Scripts for more

    - - +
    Version: 3.4.x

    Environment Variables

    Honeycomb uses environment variables to control the different configurations. Below we list the environment variables used by the app and indicate their properties via badges and text.

    NameDesktop vs OnlineBuild vs Run-timeDefault ValueTypeDescription
    REACT_APP_FIREBASEonlinebuildFalsebooleanIf the task is saving its data on Firebase.
    REACT_APP_VIDEOdesktopbuildFalsebooleanIf the participant is being video recorded.
    REACT_APP_USE_EEGdesktopbuildFalsebooleanIf the EEG (Event Marker) is available and recording.
    REACT_APP_USE_PHOTODIODEdesktopbuildFalsebooleanIf the photodiode spot is in use.
    REACT_APP_USE_VOLUMEdesktop onlinebuildFalsebooleanIf the participant should be asked to adjust their volume. (e.g. the task is using sound)
    REACT_APP_STUDY_IDdesktop onlinerun""stringThe id of a study. User will enter this value in the login screen if not set.
    REACT_APP_PARTICIPANT_IDdesktop onlinerun""stringThe id of a participant. User will enter this value in the login screen if not set.
    EVENT_MARKER_PRODUCT_IDdesktoprun""stringThe product ID of the event marker. If not set, it will default to the productID set in public/config/trigger.js. If neither are set, it will attempt to connect using the COM name.
    EVENT_MARKER_COM_NAMEdesktoprun"COM3"stringThe COM name of the event marker. If not set, it will use the comName set in public/config/trigger.js. Field is ignored if EVENT_MARKER_PRODUCT_ID is set.
    note

    Note that Honeycomb does use other environment variables (e.g., ELECTRON_START_URL) but they do not effect the task itself. They can be safely ignored.

    Understanding the Environment Variables

    Run-time

    The run badge indicates the variable is set/determined each time the executable is run. Run-time environment variables allow for quick changes when running the task. They are convenient since they don't require building a whole different executable.

    • Desktop deployments must set these environment variables at the system level.
    • Online deployments must use Firebase, and store the runtime environment variables in Firestore.

    Build-time

    The build badge indicates the variable is set during the build phase (npm run build) and cannot be changed at run-time. These variables are configured via .env files in the env folder.

    The dotenv-cli comes with the dotenv command that can be used to properly load the needed variables. We write our npm scripts with the following format:

    package.json
    "[build|dev]:<env name>": "dotenv -e env/<env name> npm run [build|dev]"

    See NPM Scripts for more

    + + \ No newline at end of file diff --git a/docs/event_triggers/index.html b/docs/event_triggers/index.html index 6142f6c8..784a39cb 100644 --- a/docs/event_triggers/index.html +++ b/docs/event_triggers/index.html @@ -3,14 +3,14 @@ -Event Triggers | Honeycomb - - +Event Triggers | Honeycomb + +
    -
    Version: 3.3.x

    Event Triggers

    BrainVision Trigger Box setup

    Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

    COMNAME

    and set the COM port to the correct value (e.g., COM3).

    Open Source Event Trigger setup

    Details on how to make the open source event trigger and photodiode can be found here.

    Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

    Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

    Send event code triggers

    Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

    Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper code (e.g. eventCode.Fixation) as input.

    Run the task with event triggers

    Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

    - - +
    Version: 3.4.x

    Event Triggers

    BrainVision Trigger Box setup

    Follow the TriggerBox setup instructions in the BrainVision Trigger Box manual. Plug the TriggerBox into the computer running the task. Check your operating system’s device list to identify the COM port that the TriggerBox is connected to. Create a new system environment variable:

    COMNAME

    and set the COM port to the correct value (e.g., COM3).

    Open Source Event Trigger setup

    Details on how to make the open source event trigger and photodiode can be found here.

    Connect the open source event trigger to the computer running the task using a USB to micro-USB cable. Check your operating system’s USB device list to identify the product ID of the teensyduino event marker.

    Create a new system environment variable: EVENT_MARKER_PRODUCT_ID and set to the product ID of the event marker.

    Send event code triggers

    Change the eventCodes values listed in the src/config/trigger.js file to the desired values. Import eventCodes from ./trigger and export as eventCodes.

    Whenever you would like to send an event code in a trial, load eventCodes from ../config/main/, and call pdSpotEncode with the proper code (e.g. eventCode.Fixation) as input.

    Run the task with event triggers

    Honeycomb automatically checks whether your event marker is connected and running at the start of the task. If it is not connected, the task will present an error and will not be able to run.

    + + \ No newline at end of file diff --git a/docs/firebase/index.html b/docs/firebase/index.html index 1a231a10..29c1698d 100644 --- a/docs/firebase/index.html +++ b/docs/firebase/index.html @@ -3,14 +3,14 @@ -Firebase | Honeycomb - - +Firebase | Honeycomb + +
    -
    Version: 3.3.x

    Firebase

    Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

    Setting up Firebase

    info

    Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

    Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

    Adding Products

    First we'll configure Firebase Hosting and Cloud Firestore on your project.

    1. Log in to Firebase with your Google account on the Firebase console

    2. Navigate to your project from the console

    3. Register a new web app to your project (Register your app)

      note

      We recommend giving your web app the same name as your task's repository

    4. Add Firestore Database to your project (Create a Cloud Firestore database)

      note

      Choose production mode for the starting mode and the default "Cloud Firestore Location"

    The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

    Installing the Command Line Interface

    The Firebase CLI is installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

    Login to Firebase
    firebase login

    A command not found error usually indicates firebase-tools has not been installed correctly. Re-running npm install -g firebase-tools should fix this issue.

    Connecting Your Firebase Project

    1. Change the default project name of your task in .firebaserc
    .firebaserc
    {
    "projects": {
    "default": "<your project name>"
    }
    }
    1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

      1. Return to your project on the Firebase console

      2. Navigate to your project setting

        Firebase project settings
      3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

        Firebase web credentials

        env/.env.firebase
        REACT_APP_FIREBASE="true"
        REACT_APP_apiKey=
        REACT_APP_authDomain=
        REACT_APP_projectId=
        REACT_APP_storageBucket=
        REACT_APP_messagingSenderId=
        REACT_APP_appId=

        Additional variables may be present in the console, they do not need to be copied.

    2. Deploy the default Firestore security rules

    Deploy Firestore rules
    firebase deploy --only firestore:rules

    Your task is now connected to an initialized Firebase project!

    Developing With Firebase

    Two terminal windows must be used while developing for Firebase. See here for instructions on splitting terminals in VSCode.

    Run Honeycomb with Firebase Enabled
    npm run dev:firebase
    Start the Firebase Emulators
    npm run firebase:emulators:start

    Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. It may be viewed on localhost:4000.

    info

    Honeycomb populates the Firestore emulators with the study s1 and participant p1.

    Deploying on Firebase

    Firebase deployments are handled automatically following Continuous Integration Continuous Development (CI/CD) practices using GitHub Actions. Here we will create custom actions that are connected to the task's Firebase project.

    Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

    Initialize Firebase hosting via Github actions
    firebase init hosting:github
    1. The window should log you in automatically; if not, follow the prompts to log in with the same account you used in the console
    2. <username>/<repository name> refers to the name of your repository in Github - be sure it's typed correctly!
    3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
    4. Enter npm install && npm run build:firebase for the prompt "What script should be run before every deploy?"
    5. Enter y to overwrite the current workflow file
    6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
    7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
    8. Enter y to overwrite the current workflow file

    Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Ensure the correct run script is present in both files.

    Github actions created by firebase

    Managing Data

    Honeycomb ships with a CLI script for managing data in Firebase. A local service account must be created in order to use it.

    Setting up a Service Account

    Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

    1. Return to the project settings your project on the Firebase console

      Firebase project settings
    2. Click on the "Service accounts" tab

    3. Near the bottom, click "Generate new Private key" and "Generate Key"

    4. Rename the key firebase-service-account.json and move it to the root directory of your task - be sure the file looks grayed out and is not picked up by git!

    danger

    A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

    Using the CLI Script

    Script Usage
    npm run cli

    The CLI script will guide you through the steps needed to manage your data appropriately:

    1. Whether you wish to download or delete data

    2. Entering the ID of a given study

    3. Entering the ID of a given participant on that study

    4. Selecting the sessions to download/delete

      info
      SPACE selects a single session and A toggles every session
    note

    The download script will prompt you for where the data should be saved. It defaults to ., which is your current folder. The folder must exist before running the script.

    Further Reading

    The Firebase Documentation details its Emulator Suite in much greater detail.

    Security Rules

    Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

    Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

    firestore.rules
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /participant_responses/{studyID}/participants/{participantID} {
    allow create, read:
    if
    // Allows any combination of studyID and participantID to be created in Firebase
    true
    // participantID must be in the registered_participants array in the registered_studies/{studyID} document
    // participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;

    // experimentID must be in the data subcollection
    match /data/{experimentID} {
    allow create, read: if true

    // trialID must be in the trials subcollection
    match /trials/{trialID} {
    allow create, read: if true
    }
    }
    }
    }
    }

    Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

    Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must use the CLI script to delete data.

    Lines 6 through 10 defines our rule for creating a document for a given participant at participant_responses/{studyID}/participants/{participantID}. Honeycomb ships with two possible rules:

    1. Line 8 specifies true which allows any combination of studyID and participantID to be created in Firebase.

      info

      This is the default rule Honeycomb ships with. It is recommended to leave this rule as is and handle the registration of studies in another tool such as Prolific.

    2. Line 10 only allows a participantID to be created if the value is in an array called registered_participants inside of a document at registered_studies/{studyID}. This ensures pre-registration of every study and participant - the next section explains how to register studies.

    caution

    Firestore rules define every valid path for data in your project. Attempting to connect anywhere besides the paths in your Firestore rules will be automatically denied, even if you have manually saved data elsewhere. This is why firestore.rules contains the nested rules in lines 12 - 20. These should be left alone.

    Registering Studies

    1. Navigate to your Firestore Database in the Firebase console

    2. Click "Start collection"

    3. Enter registered_studies as the collection ID

    4. Enter the id of your study as the document id

    5. Click "Add Field".

    6. Enter registered_participants as the field name, and set the type "array"

    7. Add the id of each study participant to the array as type "string"

      Create a study

    The study should look like this when you're finished:

    Example study

    Additional studies are created as documents inside the registered_studies collection

    - - +
    Version: 3.4.x

    Firebase

    Honeycomb comes with methods and configurations to deploy tasks with Firebase. These tools make it possible to reach a wider audience by hosting your task online.

    Setting up Firebase

    info

    Members of Brown University should submit a support ticket to have their Firebase project created. Members of other institutions should check to see if their university has access to Google Cloud.

    Otherwise, a personal Firebase account can be created for free. Please follow the firebase documentation for creating a new project.

    Adding Products

    First we'll configure Firebase Hosting and Cloud Firestore on your project.

    1. Log in to Firebase with your Google account on the Firebase console

    2. Navigate to your project from the console

    3. Register a new web app to your project (Register your app)

      note

      We recommend giving your web app the same name as your task's repository

    4. Add Firestore Database to your project (Create a Cloud Firestore database)

      note

      Choose production mode for the starting mode and the default "Cloud Firestore Location"

    The Firebase project is now fully set up! Now we'll connect your task to that project from your computer.

    Installing the Command Line Interface

    The Firebase CLI is installed with the node package manager just like the rest of Honeycomb's dependencies. Be sure to log in with same account you used when logging into the console!

    Login to Firebase
    firebase login

    A command not found error usually indicates firebase-tools has not been installed correctly. Re-running npm install -g firebase-tools should fix this issue.

    Connecting Your Firebase Project

    1. Change the default project name of your task in .firebaserc
    .firebaserc
    {
    "projects": {
    "default": "<your project name>"
    }
    }
    1. Copy the web app credentials from the Firebase console to the corresponding variables in .env.firebase

      1. Return to your project on the Firebase console

      2. Navigate to your project setting

        Firebase project settings
      3. Scroll down and copy the auto-generated values from the Firebase console to the corresponding variables in the .env.firebase file in the env folder of your Honeycomb task repo

        Firebase web credentials

        env/.env.firebase
        REACT_APP_FIREBASE="true"
        REACT_APP_API_KEY=
        REACT_APP_AUTH_DOMAIN=
        REACT_APP_PROJECT_ID=
        REACT_APP_STORAGE_BUCKET=
        REACT_APP_MESSAGING_SENDER_ID=
        REACT_APP_APP_ID=

        Additional variables may be present in the console, they do not need to be copied.

    2. Deploy the default Firestore security rules

    Deploy Firestore rules
    firebase deploy --only firestore:rules

    Your task is now connected to an initialized Firebase project!

    Developing With Firebase

    Two terminal windows must be used while developing for Firebase. See here for instructions on splitting terminals in VSCode.

    Run Honeycomb with Firebase Enabled
    npm run dev:firebase
    Start the Firebase Emulators
    npm run firebase:emulators:start

    Honeycomb is now running in the browser and connected to data on an emulated instance of Firestore. It may be viewed on localhost:4000.

    info

    Honeycomb populates the Firestore emulators with the study s1 and participant p1.

    Deploying on Firebase

    Firebase deployments are handled automatically following Continuous Integration Continuous Development (CI/CD) practices using GitHub Actions. Here we will create custom actions that are connected to the task's Firebase project.

    Execute the following command to begin initializing Firebase hosting via GitHub actions. Be sure to follow the instructions below as the prompts appear.

    Initialize Firebase hosting via Github actions
    firebase init hosting:github
    1. The window should log you in automatically; if not, follow the prompts to log in with the same account you used in the console
    2. <username>/<repository name> refers to the name of your repository in Github - be sure it's typed correctly!
    3. Enter y for the prompt "Set up the workflow to run a build script before every deploy?"
    4. Enter npm ci && npm run build:firebase for the prompt "What script should be run before every deploy?"
    5. Enter y to overwrite the current workflow file
    6. Enter y for the prompt "Set up automatic deployment to your site's live channel when a PR is merged?"
    7. Enter main for the prompt "What is the name of the GitHub branch associated with your site's live channel?"
    8. Enter y to overwrite the current workflow file
    info

    Firebase will update the files firebase-hosting-pull-request.yml and firebase-hosting-merge.yml inside the .github/workflows/ directory. Please ensure the "run" step is npm ci && npm run build:firebase in both files!

    Managing Data

    Honeycomb ships with a CLI script for managing data in Firebase. A local service account must be created in order to use it.

    Setting up a Service Account

    Service accounts are accounts that are not attached to a human user. They authorize access to a Firebase project without someone physically logging in online. We use a service account to give the download script access to the Firestore database automatically.

    1. Return to the project settings your project on the Firebase console

      Firebase project settings
    2. Click on the "Service accounts" tab

    3. Near the bottom, click "Generate new Private key" and "Generate Key"

    4. Rename the key firebase-service-account.json and move it to the root directory of your task - be sure the file looks grayed out and is not picked up by git!

    danger

    A service account has total administrative access to ts Firebase project. The file and keys inside should never be shared and never committed to GitHub.

    Using the CLI Script

    Script Usage
    npm run cli

    The CLI script will guide you through the steps needed to manage your data appropriately:

    1. Whether you wish to download or delete data

    2. Entering the ID of a given study

    3. Entering the ID of a given participant on that study

    4. Selecting the sessions to download/delete

      info
      SPACE selects a single session and A toggles every session
    note

    The download script will prompt you for where the data should be saved. It defaults to ., which is your current folder. The folder must exist before running the script.

    Further Reading

    The Firebase Documentation details its Emulator Suite in much greater detail.

    Security Rules

    Honeycomb uses security rules to authenticate participants and studies for each task. By default participants must be registered to each study in order to complete the task.

    Firestore rules are defined in the firestore.rules file in the home directory. Note the highlighted lines:

    firestore.rules
    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
    match /participant_responses/{studyID}/participants/{participantID} {
    allow create, read:
    if
    // Allows any combination of studyID and participantID to be created in Firebase
    true
    // participantID must be in the registered_participants array in the registered_studies/{studyID} document
    // participantID in get(/databases/$(database)/documents/registered_studies/$(studyID)).data.registered_participants;

    // experimentID must be in the data subcollection
    match /data/{experimentID} {
    allow create, read: if true

    // trialID must be in the trials subcollection
    match /trials/{trialID} {
    allow create, read: if true
    }
    }
    }
    }
    }

    Lines 3 and 4 indicate that Honeycomb attempts to connect to a document at /databases/{database}/documents/participant_responses/{studyID}/participants/{participantID} where studyID is a given study and participantID is a given participant within that study.

    Line 5 indicates how Honeycomb can interact with that document. Note that Honeycomb cannot update or delete data! You must use the CLI script to delete data.

    Lines 6 through 10 defines our rule for creating a document for a given participant at participant_responses/{studyID}/participants/{participantID}. Honeycomb ships with two possible rules:

    1. Line 8 specifies true which allows any combination of studyID and participantID to be created in Firebase.

      info

      This is the default rule Honeycomb ships with. It is recommended to leave this rule as is and handle the registration of studies in another tool such as Prolific.

    2. Line 10 only allows a participantID to be created if the value is in an array called registered_participants inside of a document at registered_studies/{studyID}. This ensures pre-registration of every study and participant - the next section explains how to register studies.

    caution

    Firestore rules define every valid path for data in your project. Attempting to connect anywhere besides the paths in your Firestore rules will be automatically denied, even if you have manually saved data elsewhere. This is why firestore.rules contains the nested rules in lines 12 - 20. These should be left alone.

    Registering Studies

    1. Navigate to your Firestore Database in the Firebase console

    2. Click "Start collection"

    3. Enter registered_studies as the collection ID

    4. Enter the id of your study as the document id

    5. Click "Add Field".

    6. Enter registered_participants as the field name, and set the type "array"

    7. Add the id of each study participant to the array as type "string"

      Create a study

    The study should look like this when you're finished:

    Example study

    Additional studies are created as documents inside the registered_studies collection

    + + \ No newline at end of file diff --git a/docs/gh_pages/index.html b/docs/gh_pages/index.html index da953c4a..340cf928 100644 --- a/docs/gh_pages/index.html +++ b/docs/gh_pages/index.html @@ -3,14 +3,14 @@ -GitHub Pages | Honeycomb - - +GitHub Pages | Honeycomb + +
    -
    Version: 3.3.x

    GitHub Pages

    The .github/workflows/release.yml workflow will automatically deploy your task to GitHub pages if you have it enabled for your repository. It uploads the built website to the gh-pages branch. You can then access your task at <github user>.github.io/<repository>.

    danger

    Session data is downloaded to the user's local machine upon completion of the experiment when using GH Pages. Because of this, GH Pages is not suitable for fully online experiments.

    Setup

    Please follow the GitHub documentation for setting up GH Pages on your repository and make sure the publishing source for your repository is configured for gh-pages branch.

    - - +
    Version: 3.4.x

    GitHub Pages

    The .github/workflows/release.yml workflow will automatically deploy your task to GitHub pages if you have it enabled for your repository. It uploads the built website to the gh-pages branch. You can then access your task at <github user>.github.io/<repository>.

    danger

    Session data is downloaded to the user's local machine upon completion of the experiment when using GH Pages. Because of this, GH Pages is not suitable for fully online experiments.

    Setup

    Please follow the GitHub documentation for setting up GH Pages on your repository and make sure the publishing source for your repository is configured for gh-pages branch.

    + + \ No newline at end of file diff --git a/docs/github_discussions/index.html b/docs/github_discussions/index.html index 4a1acf4b..ddb433a7 100644 --- a/docs/github_discussions/index.html +++ b/docs/github_discussions/index.html @@ -3,14 +3,14 @@ -Github Discussions | Honeycomb - - +Github Discussions | Honeycomb + +
    -
    Version: 3.3.x

    Github Discussions

    The Honeycomb repository includes a discussions board. It is a place to ask questions, share ideas, and engage with the community! Official announcements from the project are posted to the Announcements section.

    Please direct all feature requests and questions to the discussions board.

    Reporting Bugs

    Bugs with Honeycomb should be reported directly to the issues tab of the repository. Please select "Bug report" and include as much information as possible. If you are able to provide a minimal example that reproduces the bug, that is even better!

    - - +
    Version: 3.4.x

    Github Discussions

    The Honeycomb repository includes a discussions board. It is a place to ask questions, share ideas, and engage with the community! Official announcements from the project are posted to the Announcements section.

    Please direct all feature requests and questions to the discussions board.

    Reporting Bugs

    Bugs with Honeycomb should be reported directly to the issues tab of the repository. Please select "Bug report" and include as much information as possible. If you are able to provide a minimal example that reproduces the bug, that is even better!

    + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 859b0341..9df35834 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,14 +3,14 @@ -Introduction | Honeycomb - - +Introduction | Honeycomb + +
    -
    Version: 3.3.x

    Introduction

    Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that support lab equipment recordings and are ready for deployment to different settings (desktop or online) without significant changes to the code base.

    Flexible deployment online and in the lab

    Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

    Easy-to-install executables

    Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

    Foundation in jsPsych

    Honeycomb is built on top of jsPsych, a JavaScript library for running behavioral experiments in a web browser. jsPsych7 tasks can be moved directly into Honeycomb to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

    Community Driven

    Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

    Cite this work

    If you use Honeycomb in your work, please cite

    Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

    - - +
    Version: 3.4.x

    Introduction

    Honeycomb is an open source task-template repository that combines well-accepted practices and technologies from the cognitive science and web development communities to build psychophysiological tasks that support lab equipment recordings and are ready for deployment to different settings (desktop or online) without significant changes to the code base.

    Flexible deployment online and in the lab

    Honeycomb provides the ability to write one codebase and use it flexibly across settings (with guaranteed consistency in instructions, timing, etc.). The same code-base is used to maintain and deploy the identical task on Mechanical Turk, Prolific, and in research settings during concurrent electrophysiological recordings.

    Easy-to-install executables

    Deployment specifications are abstracted as parameters that are easy to configure, and application building is automated via GitHub actions providing continuous delivery of easy-to-download executables, easing setup burden across research sites.

    Foundation in jsPsych

    Honeycomb is built on top of jsPsych, a JavaScript library for running behavioral experiments in a web browser. jsPsych7 tasks can be moved directly into Honeycomb to take advantage of the flexible deployment and automated GitHub Actions workflow that Honeycomb provides.

    Community Driven

    Honeycomb additionally provides a Behavioral Task Hub at our Beehive website. These tasks are built in Honeycomb and are ready to be deployed.

    Cite this work

    If you use Honeycomb in your work, please cite

    Provenza, N.R., Gelin, L.F.F., Mahaphanit, W., McGrath, M.C., Dastin-van Rijn, E.M., Fan, Y., Dhar, R., Frank, M.J., Restrepo, M.I., Goodman, W.K. and Borton, D.A., 2021. Honeycomb: a template for reproducible psychophysiological tasks for clinic, laboratory, and home use. Brazilian Journal of Psychiatry, 44, pp.147-155.

    + + \ No newline at end of file diff --git a/docs/javascript/index.html b/docs/javascript/index.html index 252424aa..f8892db9 100644 --- a/docs/javascript/index.html +++ b/docs/javascript/index.html @@ -3,14 +3,14 @@ -JavaScript | Honeycomb - - +JavaScript | Honeycomb + + - - +
    Version: 3.4.x

    JavaScript

    Learning JavaScript

    The Mozilla Developer Network Web Docs is the gold standard for programming on the web. The JavaScript page is an excellent place for further reading about JavaScript.

    Interactive Tutorials

    Learn JavaScript is an excellent platform for beginning to learn the JavaScript programming language. It is full of interactive tutorials and small projects.

    + + \ No newline at end of file diff --git a/docs/local_application/index.html b/docs/local_application/index.html index eb9bd804..ca167e57 100644 --- a/docs/local_application/index.html +++ b/docs/local_application/index.html @@ -3,14 +3,14 @@ -Local Application | Honeycomb - - +Local Application | Honeycomb + +
    -
    Version: 3.3.x

    Local Application

    A major feature of Honeycomb is the ability to bundle JsPsych tasks into applications that can be run on any computer in a lab or clinic. Installers for these applications can be created for Windows, Mac, and Linux. The applications can be run without an internet connection, and do not require any additional software to be installed on the computer.

    Installers for these applications can be created on demand and/or automatically when a new release is created. This is called "Continuous Deployment" - more information about Honeycomb's CI/CD workflow can be found here here.

    Creating a Release

    Follow the GitHub documentation for creating a release.

    The tag should be in the format vX.X.X where X.X.X is the version number of the release. For example, if the release is version 1.0.0, the tag should be v1.0.0.

    danger

    Your release must included a new tag for the CI/CD workflow to work.

    Installing the task

    1. Navigate to the repository's "Releases" tab and select the tag you created from above
    2. Download the correct installer for your operating system
    3. Double click the installer to run it. Follow the instructions to install the application.

    Running the Task

    The task can be run by double-clicking the application icon on the desktop.

    The local application will run the task in a full-screen window. This aims to prevent study participants from doing anything else on the computer while the task is running. However, the task can be exited if needed with the following shortcut:

    + Q

    Working with Data

    Data is automatically saved throughout the task and moved to a nested folder structure on the Desktop when the task is completed. Note how the folders are organized by studyID and participantID. Each session is saved as its own .json file; it's name is the timestamp of start_date of the task.

    Early Exits

    The run-through of an experiment in which the tasks exits prematurely will NOT be sent to the desktop. However, what data was collected is available in the user's "userData" folder which can be found in the following location:

    ~/Library/Application Support/honeycomb/TempData
    caution

    The .json file will likely not be formatted correctly because of the early exit. Take extra care to fix the file before using it for data analysis.

    - - +
    Version: 3.4.x

    Local Application

    A major feature of Honeycomb is the ability to bundle JsPsych tasks into applications that can be run on any computer in a lab or clinic. Installers for these applications can be created for Windows, Mac, and Linux. The applications can be run without an internet connection, and do not require any additional software to be installed on the computer.

    Installers for these applications can be created on demand and/or automatically when a new release is created. This is called "Continuous Deployment" - more information about Honeycomb's CI/CD workflow can be found here here.

    Creating a Release

    Follow the GitHub documentation for creating a release.

    The tag should be in the format vX.X.X where X.X.X is the version number of the release. For example, if the release is version 1.0.0, the tag should be v1.0.0.

    danger

    Your release must included a new tag for the CI/CD workflow to work.

    Installing the task

    1. Navigate to the repository's "Releases" tab and select the tag you created from above
    2. Download the correct installer for your operating system
    3. Double click the installer to run it. Follow the instructions to install the application.

    Running the Task

    The task can be run by double-clicking the application icon on the desktop.

    The local application will run the task in a full-screen window. This aims to prevent study participants from doing anything else on the computer while the task is running. However, the task can be exited if needed with the following shortcut:

    + Q

    Working with Data

    Data is automatically saved throughout the task and moved to a nested folder structure on the Desktop when the task is completed. Note how the folders are organized by studyID and participantID. Each session is saved as its own .json file; it's name is the timestamp of start_date of the task.

    Early Exits

    The run-through of an experiment in which the tasks exits prematurely will NOT be sent to the desktop. However, what data was collected is available in the user's "userData" folder which can be found in the following location:

    ~/Library/Application Support/honeycomb/TempData
    caution

    The .json file will likely not be formatted correctly because of the early exit. Take extra care to fix the file before using it for data analysis.

    + + \ No newline at end of file diff --git a/docs/npm_scripts/index.html b/docs/npm_scripts/index.html index acc51811..5ce20c5a 100644 --- a/docs/npm_scripts/index.html +++ b/docs/npm_scripts/index.html @@ -3,14 +3,14 @@ -NPM Scripts | Honeycomb - - +NPM Scripts | Honeycomb + +
    -
    Version: 3.3.x

    NPM Scripts

    Custom scripts for common shell commands can be written in package.json and run via the node package manager (NPM). All of the commands needed to develop, build, and deploy Honeycomb are written as scripts.

    Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

    Executing an NPM Script
    npm run <script>

    Start

    • start runs the app in development mode and does NOT open a browser. This makes working with Electron easier as it creates its own browser for development.
    • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.
    • start:electron: Waits for the app to be running (from start) and then starts an electron process.

    Dev

    npm run dev runs the app in development mode on Electron. It executes start and start:electron concurrently.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run dev with different environment variables.

    • dev:home runs the app with equipment disabled.
    • dev:home:video runs the app with equipment disabled and video enabled.
    • dev:clinic runs the app with equipment enabled.
    • dev:clinic:video runs the app with equipment enabled and video enabled.
    • dev:turk-prolific runs the app with prolific and PsiTurk enabled.

    Firebase Development

    • dev:firebase runs the app with Firebase enabled.
    • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/.
    • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/.

    Working with Firebase is slightly different as it is meant to be run on the browser. npm run dev:firebase executes start:browser with Firebase enabled, which will automatically launch the running app in your default browser. It can be found on other browsers by navigating to localhost:3000.

    dev:firebase must be run in conjunction with firebase:emulators:start to work properly. This runs the Firebase Emulators locally with some dummy data. The emulator data can be viewed at localhost:4000.

    caution

    npm run firebase:emulators:start must be run in a separate terminal window that stays during development.

    tip

    The dummy study is s1 and the dummy participant is p1.

    Build

    npm run build creates a production build of the app in the build/ folder.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run build with different environment variables.

    • build:home builds the app with equipment disabled
    • build:home:video builds the app with equipment disabled and video enabled
    • build:clinic builds the app with equipment enabled
    • build:clinic:video builds the app with equipment enabled and video enabled
    • build:firebase builds the app with Firebase enabled
    • build:turk-prolific builds the app with prolific and PsiTurk enabled

    Package

    npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

    • npm run package:windows
    • npm run package:linux
    • npm run package:mac
    info

    Packaging for Windows on a non-Windows machine requires mono and wine to be installed.

    Miscellaneous

    • cli runs the Firebase CLI script.
    • commit runs Commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
    • format uses Prettier to style code in a consistent format.
    • lint uses Eslint to find problems in the code.
    • postinstall is run automatically after npm install and is used to rebuild the Electron dependencies
    • prepare is run automatically before the project is packaged/installed and is used to set up the project's pre-commit hooks
    • prebuild is run automatically before npm run build and is used to rebuild the Electron dependencies
    - - +
    Version: 3.4.x

    NPM Scripts

    Custom scripts for common shell commands can be written in package.json and run via the node package manager (NPM). All of the commands needed to develop, build, and deploy Honeycomb are written as scripts.

    Additional scripts can be created if desired but we generally recommend against changing or deleting the scripts Honeycomb ships with.

    Executing an NPM Script
    npm run <script>

    Start

    • start runs the app in development mode and does NOT open a browser. This makes working with Electron easier as it creates its own browser for development.
    • start:browser runs the app in development mode and automatically opens a new browser tab. It uses your system's default browser. The page will reload if you make edits.
    • start:electron: Waits for the app to be running (from start) and then starts an electron process.

    Dev

    npm run dev runs the app in development mode on Electron. It executes start and start:electron concurrently.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run dev with different environment variables.

    • dev:home runs the app with equipment disabled.
    • dev:home:video runs the app with equipment disabled and video enabled.
    • dev:clinic runs the app with equipment enabled.
    • dev:clinic:video runs the app with equipment enabled and video enabled.
    • dev:turk-prolific runs the app with prolific and PsiTurk enabled.

    Firebase Development

    • dev:firebase runs the app with Firebase enabled.
    • firebase:emulators:start starts the Firebase emulators with the data found in emulator_data/.
    • firebase:emulators:save saves the current state of the Firebase emulators into emulator_data/.

    Working with Firebase is slightly different as it is meant to be run on the browser. npm run dev:firebase executes start:browser with Firebase enabled, which will automatically launch the running app in your default browser. It can be found on other browsers by navigating to localhost:3000.

    dev:firebase must be run in conjunction with firebase:emulators:start to work properly. This runs the Firebase Emulators locally with some dummy data. The emulator data can be viewed at localhost:4000.

    caution

    npm run firebase:emulators:start must be run in a separate terminal window that stays during development.

    tip

    The dummy study is s1 and the dummy participant is p1.

    Build

    npm run build creates a production build of the app in the build/ folder.

    Note that this is a base script that other scripts build on top of - you should always run one of the scripts below while developing your app. The additional scripts execute npm run build with different environment variables.

    • build:home builds the app with equipment disabled
    • build:home:video builds the app with equipment disabled and video enabled
    • build:clinic builds the app with equipment enabled
    • build:clinic:video builds the app with equipment enabled and video enabled
    • build:firebase builds the app with Firebase enabled
    • build:turk-prolific builds the app with prolific and PsiTurk enabled

    Package

    npm run package:[platform] creates a standalone installer for the given platform using electron-forge. The installer is created in out/. Note that the scripts build the app before creating the installers

    • npm run package:windows
    • npm run package:linux
    • npm run package:mac
    info

    Packaging for Windows on a non-Windows machine requires mono and wine to be installed.

    Miscellaneous

    • cli runs the Firebase CLI script.
    • commit runs Commitizen in the console. It is useful for ensuring your Git commit messages are easy to follow.
    • format uses Prettier to style code in a consistent format.
    • lint uses Eslint to find problems in the code.
    • postinstall is run automatically after npm install and is used to rebuild the Electron dependencies
    • prepare is run automatically before the project is packaged/installed and is used to set up the project's pre-commit hooks
    • prebuild is run automatically before npm run build and is used to rebuild the Electron dependencies
    + + \ No newline at end of file diff --git a/docs/prerequisites/index.html b/docs/prerequisites/index.html index 65c00c78..d08f9b1a 100644 --- a/docs/prerequisites/index.html +++ b/docs/prerequisites/index.html @@ -3,14 +3,14 @@ -Prerequisites | Honeycomb - - +Prerequisites | Honeycomb + +
    -
    Version: 3.3.x

    Prerequisites

    It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install. This page details what programs and packages are needed to run and build Honeycomb. There are some OS-specific prerequisites needed to build a task as a desktop application.

    OS Independent

    Git

    git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

    GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

    Node Version Manager

    NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

    Python

    Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

    danger

    Honeycomb cannot use Python version 3.12 or newer. The installers will install version 3.11.

    Oracle JDk

    Java is another high-level programming language that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

    note

    Honeycomb needs Java version 11 or later to run - the installers use version 18.

    Visual Studio Code

    Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

    Mac-specific Installs

    X-Code

    XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

    Installing XCode
      xcode-select --install

    Rosetta

    Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple Silicon system.

    Windows-specific Install

    Visual Studio

    Visual Studio is a special IDE for the Windows platform. It comes with everything needed to compile desktop applications from a PC. Visual Studio Community is free to use.

    caution

    The "Desktop development with C++" workload must also be installed with Visual Studio. The automated installers should preselect this but you should double check to be certain!

    Manual Installation

    macOS

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Windows

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Linux

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

    Further Help

    If you are still having issues setting up your computer you can find the full instructions on the electron documentation for your specific OS.

    - - +
    Version: 3.4.x

    Prerequisites

    It is important that your computer is set up with the necessary packages before you begin development. You will come across a variety of errors if these prerequisites are not installed. The quick start guide explains how to run an automated install. This page details what programs and packages are needed to run and build Honeycomb. There are some OS-specific prerequisites needed to build a task as a desktop application.

    OS Independent

    Git

    git is an open-sourced version control system. It is used to track changes, revert mistakes, and enable peer code reviews!

    GitHub Desktop is a GUI application used to interact with git and GitHub directly from your computer. It is not strictly needed but many folks find it easier to work with than using git directly from the command line.

    Node Version Manager

    NodeJS is a cross-platform runtime environment for JavaScript code. Almost every web application today builds on top of node. Node Version Manager manages running multiple versions of node on the same system. The .nvmrc denotes the version of node that Honeycomb uses.

    Python

    Python is a high-level programming language. Some "under the hood" tools needed by Honeycomb are written in python so it must be installed on your system.

    Oracle JDk

    Java is another high-level programming language that some tools are written in (namely, the Firebase Emulators). We must install a JDK (Java Development Kit) for it to run.

    note

    Honeycomb needs Java version 11 or later to run - the installers use version 18.

    Visual Studio Code

    Visual Studio Code is a well-loved and easy to use integrated development environment (IDE). This is the program you'll use to write your task.

    Mac-specific Installs

    X-Code

    XCode is a special IDE for the Apple platform. It comes with everything needed to compile desktop applications from an Apple computer. It must be installed from the terminal:

    Installing XCode
      xcode-select --install

    Rosetta

    Rosetta is a translation layer built for Mac computers with Apple Silicon. It should ask to be installed if any of the prerequisite tools need it. Otherwise, this guide can be used to make sure it is on your Apple Silicon system.

    Manual Installation

    macOS

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Windows

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software.

    Linux

    The links below will take you to each project installation page should you prefer to manually install the prerequisite software. Your preferred installation method for the programs listed above should get you up and running on any Linux distro new enough to support GLIBC_2.28.

    + + \ No newline at end of file diff --git a/docs/prolific/index.html b/docs/prolific/index.html index e45e0daf..f1ba0659 100644 --- a/docs/prolific/index.html +++ b/docs/prolific/index.html @@ -3,14 +3,14 @@ -Prolific | Honeycomb - - +Prolific | Honeycomb + +
    -
    Version: 3.3.x

    Prolific

    Prolific Setup

    caution

    Prolific integration is only available in Honeycomb for tasks deployed to Firebase.

    Please follow the discussion post Configure participant and study ID in prolific to configure a Prolific study that integrates with Honeycomb.

    • The "Prolific ID" should be set to participantID
    • The "Study ID" should be set to studyID
    • The "Session ID" should be set to SESSION_ID

    Further Reading

    The jsPsych Documentation also provides a guide for Prolific integration. Please note that this documentation will differ slightly from the Honeycomb integration.

    - - +
    Version: 3.4.x

    Prolific

    Prolific Setup

    caution

    Prolific integration is only available in Honeycomb for tasks deployed to Firebase.

    Please follow the discussion post Configure participant and study ID in prolific to configure a Prolific study that integrates with Honeycomb.

    • The "Prolific ID" should be set to participantID
    • The "Study ID" should be set to studyID
    • The "Session ID" should be set to SESSION_ID

    Further Reading

    The jsPsych Documentation also provides a guide for Prolific integration. Please note that this documentation will differ slightly from the Honeycomb integration.

    + + \ No newline at end of file diff --git a/docs/psiturk/index.html b/docs/psiturk/index.html index 485258bf..92430a9b 100644 --- a/docs/psiturk/index.html +++ b/docs/psiturk/index.html @@ -3,15 +3,15 @@ -PsiTurk | Honeycomb - - +PsiTurk | Honeycomb + +
    -
    Version: 3.3.x

    PsiTurk

    While Honeycomb is optimized for use on a local application, we added functionality for usage with PsiTurk. The application will detect if it's being used in a Turk environment and will save the data to the default PsiTurk SQLite database.

    Prebuilt version

    When a GitHub Action is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts. The workflows responsible for building the PsiTurk application are .github/workflows/package.yml and .github/workflows/release.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

    If this is all you need, the build instructions below can be skipped!

    Build instructions

    To set up your PsiTurk project, we provide a script that does the conversion. -PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

    You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

    • Build the application: npm run build

    • Move to the psiturkit directory: cd psiturkit

    • If it's the first time you're running the script:

      ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>
    • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):

      ./psiturk-it -U -p <PATH_TO_NEW_PSITURK_PROJECT>

    Running PsiTurk

    After that, just navigate to your newly created PsiTurk project directory.

    shell> psiturk # start psiturk
    psiturk> server on # start server
    psiturk> debug # enter debug mode
    - - +
    Version: 3.4.x

    PsiTurk

    While Honeycomb is optimized for use on a local application, we added functionality for usage with PsiTurk. The application will detect if it's being used in a Turk environment and will save the data to the default PsiTurk SQLite database.

    Prebuilt version

    When a GitHub Action is run, a PsiTurk build will be created automatically, and can be downloaded from its artifacts. The workflows responsible for building the PsiTurk application are .github/workflows/package.yml and .github/workflows/release.yml. The first one has to be triggered manually, the latter is triggered when you tag a release.

    If this is all you need, the build instructions below can be skipped!

    Build instructions

    To set up your PsiTurk project, we provide a script that does the conversion. +PsiTurk is a Python package used to manage HITs in Mechanical Turk. Before using the provided script, install PsiTurk.

    You'll need to follow these steps (the path to the PsiTurk project should be a directory you wish to be created):

    • Build the application: npm run build

    • Move to the psiturkit directory: cd psiturkit

    • If it's the first time you're running the script:

      ./psiturk-it -p <PATH_TO_NEW_PSITURK_PROJECT>
    • To update an existing PsiTurk project (the path to the PsiTurk project should already exist from the previous steps):

      ./psiturk-it -U -p <PATH_TO_NEW_PSITURK_PROJECT>

    Running PsiTurk

    After that, just navigate to your newly created PsiTurk project directory.

    shell> psiturk # start psiturk
    psiturk> server on # start server
    psiturk> debug # enter debug mode
    + + \ No newline at end of file diff --git a/docs/quick_start/index.html b/docs/quick_start/index.html index cf48c2b4..eedad58a 100644 --- a/docs/quick_start/index.html +++ b/docs/quick_start/index.html @@ -3,14 +3,14 @@ -Quick Start | Honeycomb - - +Quick Start | Honeycomb + +
    -
    Version: 3.3.x

    Quick Start

    Creating Your Task Repository

    The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

    1. Go to the Honeycomb repository

    2. Click on Use this template and select Create a new repository.

      Use this template
    3. Enter the owner, name, and description of your repository and click on Create repository from template.

      Create the repository
      note

      We recommend creating a public repository and leaving Include all branches unchecked

    4. Ensure the repository's workflow permissions are set to "Read and write permissions"

      Settings -> Actions -> General -> Workflow permissions

      GitHub workflow permissions settings

    Additional details about template repositories can be found on the Github Docs.

    Cloning the Repository

    With the repository now setup it can be cloned onto your computer.

    1. Navigate to the repository on GitHub.

    2. Click the Code button and copy the URL

      GitHub clone repo button
    3. Open a terminal and navigate to where you want the cloned directory

    Terminal.app
    cd 'path/to/directory'
    1. Clone the repo with the following command
    Paste the URL you copied earlier
     git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
    note

    Git can be downloaded here if it is not already on your system.

    Additional details and alternative methods for cloning a repository can be found on the Github Docs.

    Installing Prerequisites

    All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

    See Prerequisites for more information about these programs.

    Initial Install

    The most commonly used package manager on macOS is Homebrew.

    1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

      /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    2. Paste the following command and follow the prompts to install the listed programs:

      brew bundle
    3. Install Xcode (not available on Homebrew)

      xcode-select --install
    note

    If you are running into issues after installing the packages, please restart your terminal and/or reboot your computer. This should resolve most issues.

    Setting Up Node

    NVM (Node Version Manager) is a tool for installing and using multiple versions on Node on your computer. It must first be installed:

    1. Install NVM

      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
    2. Copy the version number listed in .nvmrc.

      .nvmrc file
    3. Install that version.

      nvm install <VERSION>
    4. Use the needed version.

      nvm use <VERSION>
    5. Set the current version as your default

      nvm alias default node
      note

      You can skip this step if you've already set a default node version in a different project.

    Install Dependencies

    There are many Node packages used by Honeycomb that also need to be installed. Node comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

    Install Honeycomb's dependencies
    npm install

    Certain Node dependencies are best installed globally. These tools will be available from the command line anywhere on your system.

    Install Honeycomb's global dependencies
    npm install -g electron firebase-tools dotenv-cli electron lint-staged

    Run the Task

    Run the task in development mode
    npm run dev

    Running the task in development mode enables "hot reloading": changes to the code will immediately be reflected in the app without needing to restart the server.

    tip

    The dev script runs Honeycomb on Electron without any environment variables. Check out the NPM Scripts page for more information on the available development environments.

    note

    Honeycomb ships with a modified version of the "simple reaction time task" from the jsPsych tutorial. In the next section we'll create a new task and tell Honeycomb to run it!

    Edit the Task

    Now that the project is up and running we can make our first changes to the code!

    info

    The quick start guide details a command line workflow for version control. If you are unfamiliar with Git, we recommend reading the linked page before proceeding.

    1) Edit the Project Metadata

    1. Create a new branch in a separate terminal

      Create the branch edit-package-json
      git checkout -b edit-package-json
    2. Open package.json and edit it to reflect your app:

      1. name is your task's name, generally this is the name of our repository
      2. description should be rewritten to better match your task
      3. author is your lab (or PIs) name, email, and website
      4. honeycombVersion is the number currently in the version field
      5. version should then be reset to 1.0.0
      6. repository is the link the GitHub repository you created earlier.
      package.json
      {
      "name": "my-task",
      "description": "A custom task for the Honeycomb platform",
      "author": {
      "name": "My Lab",
      "email": "example@domain.com",
      "url": "https://lab-web-page.com"
      },
      "honeycombVersion": "3.3.0", // Match what was in version!
      "version": "3.3.0",
      "version": "1.0.0",
      "repository": "https://github.com/my-username/my-repository"
      },
    3. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "edit package.json with my task's information"
    4. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    2) Add a file for the task

    1. Bring your branch up to date with the main branch

      Switch to the main branch
      git checkout main
      Bring changes from GitHub into your local repository
      git pull
    2. Create a new branch (replace task-name with the name of your task)

      Check out a new branch
      git checkout -b add-<task-name>-file
    3. Add a new file inside src/experiment/ with the same name as your task

    4. Save your changes and commit them to git:

      Add the new file to Git
      git add .
      Commit all changed files with a custom message
      git commit -a -m "feat: adds file for the <task name> task"
    5. Add a taskNameOptions object to the new file (replace taskName with the name of your task)

      taskName.js
      /**
      * Experiment-wide settings for jsPsych: https://www.jspsych.org/7.3/overview/experiment-options/
      * Note that Honeycomb combines these with other options required for Honeycomb to operate correctly
      */
      export const taskNameOptions = {
      // Called when every trial finishes
      on_trial_finish: function (data) {
      console.log(`Trial ${data.internal_node_id} just finished:`, data);
      },
      // Called when the experiment finishes
      on_finish: function (data) {
      console.log("The experiment has finished:", data);
      // Reload the page for another run-through of the experiment
      window.location.reload();
      },
      };
    6. Add a buildTaskNameFunction to the new file (replace TaskName with the name of your task)

      taskName.js
      /**
      * This timeline builds the example reaction time task from the jsPsych tutorial.
      * Take a look at how the code here compares to the jsPsych documentation!
      * See the jsPsych documentation for more: https://www.jspsych.org/7.3/tutorials/rt-task/
      *
      * @param {Object} jsPsych The jsPsych instance being used to run the task
      * @returns {Object} A jsPsych timeline object
      */
      export function buildTaskNameTimeline(jsPsych) {}
    7. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds taskNameOptions and buildTaskNameTimeline to taskName.js"
    8. Edit src/experiment/index.js to use the new file

      src/experiment/index.js
      import { buildHoneycombTimeline, honeycombOptions } from "./honeycomb";
      import { buildTaskNameTimeline, taskNameOptions } from "./taskName";

      // ...

      export const jsPsychOptions = honeycombOptions;
      export const jsPsychOptions = taskNameOptions;

      // ...

      export function buildTimeline(jsPsych, studyID, participantID) {
      console.log(`Building timeline for participant ${participantID} on study ${studyID}`);

      const timeline = buildHoneycombTimeline(jsPsych);
      const timeline = buildTaskNameTimeline(jsPsych);
      return timeline;
      }
    9. Run the format script to make sure the code is formatted correctly

      npm run format
    10. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "fix: Use new task's file"
    11. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    3) Add some trials to the task

    1. Bring your branch up to date with the main branch

      Switch to the main branch
      git checkout main
      Bring changes from GitHub into your local repository
      git pull
    2. Create a new branch

      Bring changes from GitHub into your local repository
      git checkout -b add-start-procedure
    3. Add the start procedure to the buildTaskNameTimeline function in the file you created earlier

      taskName.js
      import { buildStartProcedure } from "./procedures/startProcedure";

      // ...

      export function buildTaskNameTimeline(jsPsych) {
      // Build the trials that make up the start procedure
      const startProcedure = buildStartProcedure(jsPsych);

      const timeline = [startProcedure];
      return timeline;
      }

      // ...
    4. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds startProcedure to the task"
    5. Edit the text for the task's name

      src/config/language.json
      {
      "name": "taskName"
      // ...
      }
      tip

      The text for the introduction trial is in src/config/language.json under the trials and introduction key.

      src/config/language.json
       {
      "name": "taskName"
      // ...
      "trials": {
      "introduction": "Welcome to the experiment. Press any key to begin."
      // ...
      },
      // ...
      }
    6. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: Updates the language for the startProcedure of the task"
    7. Add the end procedure to the buildTaskNameTimeline function in the file you created earlier

      taskName.js
      import { buildStartProcedure } from "./procedures/startProcedure";
      import { buildEndProcedure } from "./procedures/endProcedure";

      // ...

      export function buildTaskNameTimeline(jsPsych) {
      // Build the trials that make up the start procedure
      const startProcedure = buildStartProcedure(jsPsych);

      // Builds the trials that make up the end procedure
      const endProcedure = buildEndProcedure(jsPsych);

      const timeline = [startProcedure, endProcedure];
      return timeline;
      }
      // ...
      tip

      The text for the conclusion trial is in src/config/language.json under the trials and conclusion key.

      src/config/language.json
       {
      "name": "taskName"
      // ...
      "trials": {
      // ...
      "conclusion": "Welcome to the experiment. Press any key to begin."
      },
      }
    8. Run a format to make sure the code is formatted correctly

      npm run format
    9. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds endProcedure to the task"
    10. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    Next Steps

    • The Firebase page explains how to set up your task with Firebase.
    • The Environment Variables page explains how to configure your task for deployment to multiple scenarios.
    • The NPM Scripts page lists every script you can run and which environment they use.
    - - +
    Version: 3.4.x

    Quick Start

    Creating Your Task Repository

    The Honeycomb repository is a template and serves as the starting point for all tasks. Creating your repository from the template starts your project with the same directory structure and files as an existing repository.

    1. Go to the Honeycomb repository

    2. Click on Use this template and select Create a new repository.

      Use this template
    3. Enter the owner, name, and description of your repository and click on Create repository from template.

      Create the repository
      note

      We recommend creating a public repository and leaving Include all branches unchecked

    4. Ensure the repository's workflow permissions are set to "Read and write permissions"

      Settings -> Actions -> General -> Workflow permissions

      GitHub workflow permissions settings

    Additional details about template repositories can be found on the Github Docs.

    Cloning the Repository

    With the repository now setup it can be cloned onto your computer.

    1. Navigate to the repository on GitHub.

    2. Click the Code button and copy the URL

      GitHub clone repo button
    3. Open a terminal and navigate to where you want the cloned directory

    Terminal.app
    cd 'path/to/directory'
    1. Clone the repo with the following command
    Paste the URL you copied earlier
     git clone https://github.com/<YOUR-USERNAME>/<YOUR-REPOSITORY>
    note

    Git can be downloaded here if it is not already on your system.

    Additional details and alternative methods for cloning a repository can be found on the Github Docs.

    Installing Prerequisites

    All of the needed programs for Honeycomb must be installed before we can develop our task. We will use a package manager to automatically install them.

    See Prerequisites for more information about these programs.

    Initial Install

    The most commonly used package manager on macOS is Homebrew.

    1. Paste the following command in a macOS Terminal and follow the prompts to install Homebrew.

      /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    2. Paste the following command and follow the prompts to install the listed programs:

      brew bundle
    3. Install Xcode (not available on Homebrew)

      xcode-select --install
    note

    If you are running into issues after installing the packages, please restart your terminal and/or reboot your computer. This should resolve most issues.

    Setting Up Node

    NVM (Node Version Manager) is a tool for installing and using multiple versions on Node on your computer. It must first be installed:

    1. Install NVM

      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash
    2. Copy the version number listed in .nvmrc.

    3. Install that version.

      nvm install <VERSION>
    4. Use the needed version.

      nvm use <VERSION>
    5. Set the current version as your default

      nvm alias default node
      note

      You can skip this step if you've already set a default node version in a different project.

    Install Dependencies

    There are many Node packages used by Honeycomb that also need to be installed. Node comes with its own package manager to install, update, and maintain these dependencies throughout the development lifecycle.

    Install Honeycomb's dependencies
    npm install

    Certain Node dependencies are best installed globally. These tools will be available from the command line anywhere on your system.

    Install Honeycomb's global dependencies
    npm install -g electron firebase-tools dotenv-cli electron lint-staged

    Run the Task

    Run the task in development mode
    npm run dev

    Running the task in development mode enables "hot reloading": changes to the code will immediately be reflected in the app without needing to restart the server.

    tip

    The dev script runs Honeycomb on Electron without any environment variables. Check out the NPM Scripts page for more information on the available development environments.

    note

    Honeycomb ships with a modified version of the "simple reaction time task" from the jsPsych tutorial. In the next section we'll create a new task and tell Honeycomb to run it!

    Edit the Task

    Now that the project is up and running we can make our first changes to the code!

    info

    The quick start guide details a command line workflow for version control. If you are unfamiliar with Git, we recommend reading the linked page before proceeding.

    1) Edit the Project Metadata

    1. Create a new branch in a separate terminal

      Create the branch edit-package-json
      git checkout -b edit-package-json
    2. Open package.json and edit it to reflect your app:

      1. name is your task's name, generally this is the name of our repository
      2. description should be rewritten to better match your task
      3. author is your lab (or PIs) name, email, and website
      4. honeycombVersion is the number currently in the version field
      5. version should then be reset to 1.0.0
      6. repository is the link the GitHub repository you created earlier.
      package.json
      {
      "name": "my-task",
      "description": "A custom task for the Honeycomb platform",
      "author": {
      "name": "My Lab",
      "email": "example@domain.com",
      "url": "https://lab-web-page.com"
      },
      "honeycombVersion": "3.3.0", // Match what was in version!
      "version": "3.3.0",
      "version": "1.0.0",
      "repository": "https://github.com/my-username/my-repository"
      },
    3. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "edit package.json with my task's information"
    4. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    2) Add a file for the task

    1. Bring your branch up to date with the main branch

      Switch to the main branch
      git checkout main
      Bring changes from GitHub into your local repository
      git pull
    2. Create a new branch (replace task-name with the name of your task)

      Check out a new branch
      git checkout -b add-<task-name>-file
    3. Add a new file inside src/experiment/ with the same name as your task

    4. Save your changes and commit them to git:

      Add the new file to Git
      git add .
      Commit all changed files with a custom message
      git commit -a -m "feat: adds file for the <task name> task"
    5. Add a taskNameOptions object to the new file (replace taskName with the name of your task)

      taskName.js
      /**
      * Experiment-wide settings for jsPsych: https://www.jspsych.org/7.3/overview/experiment-options/
      * Note that Honeycomb combines these with other options required for Honeycomb to operate correctly
      */
      export const taskNameOptions = {
      // Called when every trial finishes
      on_trial_finish: function (data) {
      console.log(`Trial ${data.internal_node_id} just finished:`, data);
      },
      // Called when the experiment finishes
      on_finish: function (data) {
      console.log("The experiment has finished:", data);
      // Reload the page for another run-through of the experiment
      window.location.reload();
      },
      };
    6. Add a buildTaskNameFunction to the new file (replace TaskName with the name of your task)

      taskName.js
      /**
      * This timeline builds the example reaction time task from the jsPsych tutorial.
      * Take a look at how the code here compares to the jsPsych documentation!
      * See the jsPsych documentation for more: https://www.jspsych.org/7.3/tutorials/rt-task/
      *
      * @param {Object} jsPsych The jsPsych instance being used to run the task
      * @returns {Object} A jsPsych timeline object
      */
      export function buildTaskNameTimeline(jsPsych) {}
    7. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds taskNameOptions and buildTaskNameTimeline to taskName.js"
    8. Edit src/experiment/index.js to use the new file

      src/experiment/index.js
      import { buildHoneycombTimeline, honeycombOptions } from "./honeycomb";
      import { buildTaskNameTimeline, taskNameOptions } from "./taskName";

      // ...

      export const jsPsychOptions = honeycombOptions;
      export const jsPsychOptions = taskNameOptions;

      // ...

      export function buildTimeline(jsPsych, studyID, participantID) {
      console.log(`Building timeline for participant ${participantID} on study ${studyID}`);

      const timeline = buildHoneycombTimeline(jsPsych);
      const timeline = buildTaskNameTimeline(jsPsych);
      return timeline;
      }
    9. Run the format script to make sure the code is formatted correctly

      npm run format
    10. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "fix: Use new task's file"
    11. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    3) Add some trials to the task

    1. Bring your branch up to date with the main branch

      Switch to the main branch
      git checkout main
      Bring changes from GitHub into your local repository
      git pull
    2. Create a new branch

      Bring changes from GitHub into your local repository
      git checkout -b add-start-procedure
    3. Add the start procedure to the buildTaskNameTimeline function in the file you created earlier

      taskName.js
      import { buildStartProcedure } from "./procedures/startProcedure";

      // ...

      export function buildTaskNameTimeline(jsPsych) {
      // Build the trials that make up the start procedure
      const startProcedure = buildStartProcedure(jsPsych);

      const timeline = [startProcedure];
      return timeline;
      }

      // ...
    4. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds startProcedure to the task"
    5. Edit the text for the task's name

      src/config/language.json
      {
      "name": "taskName"
      // ...
      }
      tip

      The text for the introduction trial is in src/config/language.json under the trials and introduction key.

      src/config/language.json
       {
      "name": "taskName"
      // ...
      "trials": {
      "introduction": "Welcome to the experiment. Press any key to begin."
      // ...
      },
      // ...
      }
    6. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: Updates the language for the startProcedure of the task"
    7. Add the end procedure to the buildTaskNameTimeline function in the file you created earlier

      taskName.js
      import { buildStartProcedure } from "./procedures/startProcedure";
      import { buildEndProcedure } from "./procedures/endProcedure";

      // ...

      export function buildTaskNameTimeline(jsPsych) {
      // Build the trials that make up the start procedure
      const startProcedure = buildStartProcedure(jsPsych);

      // Builds the trials that make up the end procedure
      const endProcedure = buildEndProcedure(jsPsych);

      const timeline = [startProcedure, endProcedure];
      return timeline;
      }
      // ...
      tip

      The text for the conclusion trial is in src/config/language.json under the trials and conclusion key.

      src/config/language.json
       {
      "name": "taskName"
      // ...
      "trials": {
      // ...
      "conclusion": "Welcome to the experiment. Press any key to begin."
      },
      }
    8. Run a format to make sure the code is formatted correctly

      npm run format
    9. Save your changes and commit them to git:

      Commit all changed files with a custom message
      git commit -a -m "feat: adds endProcedure to the task"
    10. Create and merge a pull request to merge your changes into the main branch. Make sure the builds complete successfully before merging!

    Next Steps

    • The Firebase page explains how to set up your task with Firebase.
    • The Environment Variables page explains how to configure your task for deployment to multiple scenarios.
    • The NPM Scripts page lists every script you can run and which environment they use.
    + + \ No newline at end of file diff --git a/docs/troubleshooting/index.html b/docs/troubleshooting/index.html index 8d2af04d..5ed9da27 100644 --- a/docs/troubleshooting/index.html +++ b/docs/troubleshooting/index.html @@ -3,14 +3,14 @@ -Troubleshooting | Honeycomb - - +Troubleshooting | Honeycomb + +
    -
    Version: 3.3.x

    Troubleshooting

    Inspecting Errors

    When running any of the npm run dev commands you may encounter errors. These may display over the window itself or may may exist in the developer tools. These tools can be accessed by right clicking the window and selecting "Inspect" or by pressing Ctrl+Shift+I (Cmd+Option+I on Mac). The errors, as well as any console.logs, will be displayed in the "Console" tab of the developer tools.

    When developing Electron apps there are two processes: main, and renderer. In this case, main corresponds to public/electron/main.js and its console is in the terminal where npm run devwas run. renderer corresponds to the React App - this is everything else. This console can be found using the same steps as above - note that running npm run dev should open the developer console by default.

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Most npm issues can be resolved by re-installing dependencies. This can be done by running the following commands in the root directory of the project:

    1. Delete the node_modules/ folder
    2. Delete hte package-lock.json file
    3. Reinstall dependencies
      npm install
    - - +
    Version: 3.4.x

    Troubleshooting

    Inspecting Errors

    When running any of the npm run dev commands you may encounter errors. These may display over the window itself or may may exist in the developer tools. These tools can be accessed by right clicking the window and selecting "Inspect" or by pressing Ctrl+Shift+I (Cmd+Option+I on Mac). The errors, as well as any console.logs, will be displayed in the "Console" tab of the developer tools.

    When developing Electron apps there are two processes: main, and renderer. In this case, main corresponds to public/electron/main.js and its console is in the terminal where npm run devwas run. renderer corresponds to the React App - this is everything else. This console can be found using the same steps as above - note that running npm run dev should open the developer console by default.

    Common issues

    Installing Dependencies

    Brew Not Available

    If you run into issues installing Homebrew in step 1 of Installing Prerequisites it may be because Homebrew is not available on your shell. Older versions of macOS (under 10.14) do not do this automatically.

    Run the following command to manually add the Homebrew installation location to your PATH so it is available in your shell.

    echo 'PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
    note

    If you're using zsh, also add to your ~/.zshrc file.

    NPM Errors

    Most npm issues can be resolved by re-installing dependencies. This can be done by running the following commands in the root directory of the project:

    1. Delete the node_modules/ folder
    2. Delete hte package-lock.json file
    3. Reinstall dependencies
      npm install
    + + \ No newline at end of file diff --git a/docs/variants/index.html b/docs/variants/index.html index 0d0ea48f..7b5e440e 100644 --- a/docs/variants/index.html +++ b/docs/variants/index.html @@ -3,14 +3,14 @@ -Variants | Honeycomb - - +Variants | Honeycomb + +
    -
    Version: 3.3.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    - - +
    Version: 3.4.x

    Variants

    Variant-specific Executables

    In order to create multiple variants of a task that can be co-installed, it is necessary to add new scripts to the package.json file in addition to creating the necessary environment variables for configuration. Each variant must have a unique, lowercase name. Optionally, a unique icon can be used for each variant by saving multiple icons to the icons directories with the same names as the variants. Example scripts for Windows, Mac, and Linux are shown below.

    Windows:

    "package:windows:<task_name>": "electron-packager . <task_name> --platform win32 --arch x64 --icon ./assets/icons/win/<task_name> --out dist/ --overwrite --asar"
    "postpackage:windows:<task_name>": "electron-installer-windows --src dist/<task_name>-win32-x64/ --dest dist/installers/ --overwrite --homepage https://ccv.brown.edu/ --name <task_name> --exe <task_name>.exe --productName <task_name>"

    Mac:

    "package:mac:,<task_name>": "electron-packager . <task_name> --platform darwin --arch x64 --out dist/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"
    "installer:mac:<task_name>": "electron-installer-dmg ./dist/<task_name>-darwin-x64/<task_name>.app <task_name>-${npm_package_version} --out ./dist/installers/ --icon ./assets/icons/mac/<task_name>.icns --overwrite"

    Linux:

    "package:linux:<task_name>": "electron-packager . <task_name> --platform linux --arch x64 --icon ./assets/icons/mac/<task_name> --out dist/ --overwrite"
    "postpackage:linux:<task_name>": "electron-installer-debian --src dist/<task_name>-linux-x64/ --dest dist/installers/ --arch x64 --overwrite --name <task_name> --productName <task_name> --genericName <task_name> --bin <task_name>"

    Variant-specific Workflows

    In order to use Github workflows to build and upload executables for each variant, the build.yaml, package.yaml, and release.yaml files must be modified as well. For all three files, a new row should be added to the matrix variable as follows:

    variant: [<comma_separated_list_of_variant_names>]

    Add the following before npm build in the steps section of build.yaml, package.yaml, and release.yaml:

    - name: Load .env file for variant
    uses: xom9ikk/dotenv@v1.0.2
    with:
    path: ./env
    mode: ${{matrix.variant}}

    In package.yaml and release.yaml, replace the # Build electron app package installers section with the following code:

    - name: package electron - windows
    if: startsWith(matrix.os, 'windows')
    run: npm run package:windows:${{ matrix.variant }}
    - name: package electron - linux
    if: startsWith(matrix.os, 'ubuntu')
    run: npm run package:linux:${{ matrix.variant }}
    - name: package electron - mac
    if: startsWith(matrix.os, 'mac')
    run: npm run package:mac:${{ matrix.variant }}
    - name: npm rebuild - mac
    if: startsWith(matrix.os, 'mac')
    run: npm rebuild
    - name: Mac installer
    if: startsWith(matrix.os, 'mac')
    run: npm run installer:mac:${{ matrix.variant }}

    Replace the # Upload installers to github action section in package.yaml with the following code:

    - name: upload win-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'windows')
    with:
    name: ${{ format('win-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    - name: upload mac-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'mac')
    with:
    name: ${{ format('mac-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    - name: upload linux-installer
    uses: actions/upload-artifact@master
    if: startsWith(matrix.os, 'ubuntu')
    with:
    name: ${{ format('linux-installer-{0}', github.event.inputs.setting) }}
    path: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb

    Replace the # Upload installers to github release section in release.yaml with the following code:

    - name: Upload app to release - windows
    if: startsWith(matrix.os, 'windows')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-setup.exe
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}-setup.exe
    tag: ${{ github.ref }}
    - name: Upload app to release - linux
    if: startsWith(matrix.os, 'ubuntu')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_x64.deb
    asset_name: ${{ matrix.variant }}_${{ steps.package_info.outputs.package_version }}_${{ matrix.setting }}_x64.deb
    tag: ${{ github.ref }}
    - name: Upload app to release - mac
    if: startsWith(matrix.os, 'mac')
    uses: svenstaro/upload-release-action@v2
    with:
    repo_token: ${{ secrets.GITHUB_TOKEN }}
    file: dist/installers/${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}.dmg
    asset_name: ${{ matrix.variant }}-${{ steps.package_info.outputs.package_version }}-${{ matrix.setting }}.dmg
    tag: ${{ github.ref }}
    + + \ No newline at end of file diff --git a/docs/version_control/index.html b/docs/version_control/index.html index 22c1bc64..72a9c44a 100644 --- a/docs/version_control/index.html +++ b/docs/version_control/index.html @@ -3,14 +3,14 @@ -Version Control | Honeycomb - - +Version Control | Honeycomb + +
    -
    Version: 3.3.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, with the exception of a few used to synchronize with the GitHub remote host. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branches diagram

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    Create a pull requestAdd reviewers to a pull request

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button. Note how the branch name describes the changes.

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main
    • Perform tests and code reviews before merges into main, not afterwards
    • Every branch starts from main, and targets main
    • Commit messages reflect intent

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout -b <branch>create and checkout a new branch
    git checkout <branch>checkout the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    GUI Based Source Control

    • VS Code is the default IDE installed by Honeycomb. Check out this overview of source control in VS Code!
    • GitHub Desktop is a GUI application built specifically for working with Git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes from the template repository. It is tedious, but extremely import, to not accidentally overwrite your task when resolving these conflicts.

    - - +
    Version: 3.4.x

    Version Control

    Git Overview

    Git is a version control system that enables you to track changes to files. With Git, you are able to revert files back to previous versions, restore deleted files, remove added files and even track down where a particular line of code was introduced.

    Nearly all operations that are performed by Git are in your local computing environment, with the exception of a few used to synchronize with the GitHub remote host. Some of the most common git operations are depicted below.

    Git basics

    If you would like to make any changes to current repository, it is always good to start with creating a feature branch, where you can save all the changes.

    Example branches diagram

    Create a Pull Request

    Pull requests are useful before you merge your branch with the main branch. You can request a review from your colleagues and check for any conflicts with the main branch. After you pushed all the changes to your branch, you can go to the original GitHub repository and click on the pull request.

    Create a pull requestAdd reviewers to a pull request

    Best Practices

    Git Branches

    • main is the default branch and where releases are made from. This branch should be in clean/working conditions at all times. This branch is protected and can only be merged from Pull Requests for topic branches.

    • topic branches are created for new features, fixes, or really any changes. E.g, fix-task-trial2-stuck-button. Note how the branch name describes the changes.

    This flow is sometimes referred to as Feature Branch Workflow

    Basic Workflow

    We recommend using a simple flow based on following rules:

    • Use topic/feature branches, no direct commits on main
    • Perform tests and code reviews before merges into main, not afterwards
    • Every branch starts from main, and targets main
    • Commit messages reflect intent

    Comment styles

    We encourage using Commitizen, a great tool for recording descriptions of commits in a standardized format which makes it easier for people to understand what changed in the code.

    Git Commands

    CommandBrief
    git add <files>add a file to next commit (stage)
    git commit -m <message>commit staged files
    git pushupload staged commit to repo
    git pullget remote repo commits and download (try and resolve conflicts)
    git clone <url>download entire repository
    git checkout -b <branch>create and checkout a new branch
    git checkout <branch>checkout the branch you want to use
    # create branch with your feature
    git checkout -b feature_name
    # check the status of your repositoey
    git status
    # commit file contents to the local repository
    git commit -m "My feature is ready"

    # specific message
    # push file contents to the remote (i.e. cloud) repository
    git push origin feature_name

    GUI Based Source Control

    • VS Code is the default IDE installed by Honeycomb. Check out this overview of source control in VS Code!
    • GitHub Desktop is a GUI application built specifically for working with Git. It is one of the programs installed as a prerequisite of Honeycomb. Check out this overview of source control in GitHub Desktop!

    Stay up-to-date with Honeycomb template repo

    Honeycomb is an active project, and will be updated with new features over time. To bring changes from the Honeycomb template repository to your task:

    1. Add Honeycomb as an additional remote as follows:

      git remote add honeycomb https://github.com/brown-ccv/honeycomb.git
    2. Fetch the changes made to Honeycomb

      git fetch --all
    3. Merge the current Honeycomb repo

      git merge honeycomb/main --allow-unrelated histories
    caution

    There will almost certainly be many "merge conflicts" when merging in changes from the template repository. It is tedious, but extremely import, to not accidentally overwrite your task when resolving these conflicts.

    + + \ No newline at end of file diff --git a/index.html b/index.html index 1d647f95..504634ac 100644 --- a/index.html +++ b/index.html @@ -3,14 +3,14 @@ -Honeycomb | Honeycomb - - +Honeycomb | Honeycomb + +
    -

    Honeycomb

    A template for reproducible psychophysiological tasks for clinic, laboratory, and home use.

    Modular and Configurable

    Modular and Configurable

    Honeycomb was designed to be modular, composable, easily configured to deploy to Linux, Mac, Windows, Browsers, PsiTurk, and more

    Packed with automation

    Packed with automation

    Honeycomb includes GitHub Actions that build the executables/deployments for you.

    Based on trusted and mature libraries

    Based on trusted and mature libraries

    Honeycomb relies on mature libraries such as JSPsych, React and Electron

    - - +

    Honeycomb

    A template for reproducible psychophysiological tasks for clinic, laboratory, and home use.

    Modular and Configurable

    Modular and Configurable

    Honeycomb was designed to be modular, composable, easily configured to deploy to Linux, Mac, Windows, Browsers, PsiTurk, and more

    Packed with automation

    Packed with automation

    Honeycomb includes GitHub Actions that build the executables/deployments for you.

    Based on trusted and mature libraries

    Based on trusted and mature libraries

    Honeycomb relies on mature libraries such as JSPsych, React and Electron

    + + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index aa8a9da1..4edab897 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/configurationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/foldersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/online_integrationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/software_prerecsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/configurationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/foldersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/online_integrationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/software_prerecsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/configurationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/foldersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/online_integrationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/setup_detailsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/deploy_onlineweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/project_organizationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/ci_cdweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/directory_structureweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/gh_pagesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/local_applicationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/psiturkweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/ci_cdweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/directory_structureweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/gh_pagesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/github_discussionsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/local_applicationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/prolificweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/psiturkweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/weekly0.5 \ No newline at end of file +https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/configurationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/foldersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/online_integrationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/software_prerecsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/1.1.0/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/configurationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/foldersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/online_integrationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/software_prerecsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/2.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/configurationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/foldersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/online_integrationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/setup_detailsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.0.0/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/ciweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/deploy_onlineweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/project_organizationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.1.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/ci_cdweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/directory_structureweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/gh_pagesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/local_applicationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/psiturkweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.2.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/ci_cdweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/directory_structureweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/gh_pagesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/github_discussionsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/local_applicationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/prolificweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/psiturkweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/3.3.x/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/weekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/ci_cdweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/directory_structureweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/environment_variablesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/event_triggersweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/firebaseweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/gh_pagesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/github_discussionsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/javascriptweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/local_applicationweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/npm_scriptsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/prerequisitesweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/prolificweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/psiturkweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/quick_startweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/troubleshootingweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/variantsweekly0.5https://brown-ccv.github.io/honeycomb-docs/docs/version_controlweekly0.5https://brown-ccv.github.io/honeycomb-docs/weekly0.5 \ No newline at end of file